2013-04-11 42 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
Content Enricher頁面存在警告,稱「pollEnrich無法訪問當前Exchange中的任何數據」。
好像pollEnrich不支持URL(link)指定的動態fileName:但是如果我添加fileName=${body}到文件URL

UPD2沒有什麼變化。路線在目前的時刻:

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()); 
} 

現在,返回上第一響應文件的內容,但對每個後續請求我得到了以上日誌消息的永恆循環:

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

UPD4
我已經實現了動態路由,它在處理之前被添加並在其後被刪除。這個方法在Apache Camel論壇的this文章中有描述。路由使用上面的處理器來使用文件。結果是一樣的

回答

9

簡單的方法往往是最好的方法。我拒絕處理在這種情況下Apache的駱駝文件組件,並實現以下處理器:

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); 
} 

現在,它的工作就像一個魅力

+0

您可以顯示DSL是什麼樣子使用自定義的處理器?有沒有辦法將自定義處理器傳遞給pollEnrich? – pimlottc 2015-02-03 22:52:11