2013-04-11 3 views
6

일부 요청에 대해 파일을 반환해야하는 RESTful 서비스 (CXFRS 구성 요소 사용)를 구현 중입니다. 각 파일은 ID와 확장자 (예 : restfulservice.com/path/file/1/pdf)로 가져옵니다. 한번 추가 된 각 파일은 절대로 변경되지 않습니다. 파일을 가져온 후에는 파일을 이동하거나 삭제하지 말아야하며 일반적으로 파일을 동시에 액세스 할 수 있어야합니다. 여기 내 낙타 컨텍스트의 일부입니다Apache Camel 요청시 파일 내용이 풍부한 메시지

from("direct:fetchFile") 
    .process(fetchFileProcessor) // set file.id & file.extension 
    .bean(fileService, "fetchFile(${header.file.id}, ${header.file.extension})") // set body to filename 
    .setHeader("CamelFileName", simple("${body}")) 
    .choice() 
     .when(header("file.extension").isEqualTo("xml")) 
      .pollEnrich("file:///{{application.fileStorage.basePath}}/xml?noop=true", 500) 
     .when(header("file.extension").isEqualTo("pdf")) 
      .pollEnrich("file:///{{application.fileStorage.basePath}}/pdf?noop=true", 500) 
    .end() 
    .convertBodyTo(File.class) 
    .bean(responseProvider, "getResponse(${body}, 200)"); 

이 구성의 문제는 응답 시간 제한 설정 서비스하지 않고, 단지 두 번째 (왜?) 요청 비어 있지 않은 몸을 가지고 있다는 것입니다 디버그와 두 번째 요청에 영원한 루프에 들어갑니다 메시지

DEBUG o.a.c.c.f.FileConsumer - Took 0.000 seconds to poll <base path>\xml 

빨리 낙타 버전 2.10.4

입니다 어떤 도움을 주시면 감사하겠습니다

UPD1 :
페이지에 'pollEnrich가 현재 Exchange의 데이터에 액세스하지 못했습니다.'라는 경고가 표시됩니다. 그것은 pollEnrich처럼 보인다
는 URL (link)에 지정된 동적 fileName을 지원하지 않습니다 : 나는 URL

UPD2에게 파일에 fileName=${body}를 추가한다면 아무것도 변경되지 않습니다. 현재의 순간에 경로는 :

from("direct:fetchFile") 
    .process(fetchFileProcessor) // set file.id & file.extension 
    .bean(fileService, "fetchFile(${header.file.id}, ${header.file.extension})") // set body to filename 
    .choice() 
     .when(header("file.extension").isEqualTo("xml")) 
      .pollEnrich("file:///{{application.fileStorage.basePath}}/xml?fileName=${body}&noop=true", 500) 
      .setHeader("asset.type", simple(MediaType.APPLICATION_XML)) 
     .when(header("file.extension").isEqualTo("pdf")) 
      .pollEnrich("file:///{{application.fileStorage.basePath}}/pdf?fileName=${body}&noop=true", 500) 
      .setHeader("asset.type", simple("application/pdf")) 
    .end() 
    .convertBodyTo(File.class) 
    .process(multipartProcessor) // add file ass attachment to multipart body and set it as body 
    .bean(responseProvider, "getResponse(${body}, 200)"); 

UPD3
나는 동적 파일 이름 PollingConsumer를 사용하는 사용자 정의 프로세서를 구현하기 위해 노력하고있어 :

@Override 
public void process(Exchange exchange) throws Exception { 
    Long timeout = exchange.getIn().getHeader("file.timeout", Long.class); 
    if (enrichUri == null) { 
     throw new FileNotFoundException("'file.url' header not set"); 
    } 

    CamelContext context = exchange.getContext(); 
    Endpoint endpoint = context.getEndpoint(enrichUri); 
    PollingConsumer consumer = endpoint.createPollingConsumer(); 
    consumer.start(); 

    Exchange consumedExchange; 
    try { 
     if (timeout == null || timeout < 0) { 
      consumedExchange = consumer.receive(); 
     } else if (timeout == 0) { 
      consumedExchange = consumer.receiveNoWait(); 
     } else { 
      consumedExchange = consumer.receive(timeout); 
     } 
    } catch (Exception e) { 
     throw new AssetNotFoundException(e); 
    } finally { 
     consumer.stop(); 
    } 
    exchange.getIn().setBody(consumedExchange.getIn().getBody()); 
} 

지금은 첫 번째 응답에 파일 내용을 반환 그러나 각각의 이어지는 요청에서 나는 위의 로그 메시지의 영원한 반복을 얻었다 :

UPD4
처리하기 전에 추가 된 동적 경로를 구현하고 제거했습니다. 이 방법은 Apache Camel 포럼의 this 게시물에 설명되어 있습니다. 경로는 프로세서를 사용하여 파일을 사용합니다. 결과는 동일합니다

답변

9

간단한 방법은 종종 가장 좋은 방법입니다.

public class FileLoadingProcessor implements Processor { 

@Override 
public void process(Exchange exchange) throws Exception { 
    String filename = exchange.getIn().getBody(String.class); // message body contains filename 
    String filePath = exchange.getIn().getHeader("fileprocessor.filepath", String.class); 

    if (filePath == null || filename == null) { 
     // throw some custom exception 
    } 

    URI uri = new URI(filePath.concat(filename)); 
    File file = new File(uri); 

    if (!file.exists()) { 
     throw new FileNotFoundException(String.format("File %s not found on %s", filename, filePath)); 
    } 

    exchange.getIn().setBody(file); 
} 

이 지금은 매력 당신은 DSL 사용자 정의 프로세서를 사용하는 모습을 보여줄 수

+0

처럼 일하고 : I 프로세서 다음이 경우 아파치 낙타 파일 컴포넌트 처리를 거부하고 구현? pollEnrich에 맞춤형 프로세서를 전달하는 방법이 있습니까? – pimlottc