2013-04-11 10 views
6

Sto implementando il servizio RESTful (utilizzando il componente CXFRS) che dovrebbe restituire i file per alcune richieste. Ogni file viene recuperato dall'ID e dall'estensione, ad esempio restfulservice.com/path/file/1/pdf. Ogni file aggiunto non cambia mai. I file non devono essere spostati o cancellati dopo il recupero e generalmente dovrebbero essere accessibili contemporaneamente. Ecco parte del mio contesto Camel:Apache Camel arricchisce il messaggio con il contenuto del file su richiesta

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

Il problema con questa configurazione è che la risposta ha il corpo non vuoto solo per seconda richiesta (perché?), Senza servizio di timeout impostato entra sul ciclo eterno sulla seconda richiesta con il debug messaggio versione

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

Apace Camel è 2.10.4

Qualsiasi aiuto sarebbe apprezzato

UPD1:
C'è un avviso nella pagina Content Enricher, che dice "pollEnrich non accede ai dati dallo scambio corrente". Ma nulla cambia se aggiungo fileName=${body} di presentare URL

UPD2:
Sembra pollEnrich non supportano dinamica fileName specificato nella URL (link). Percorso al momento attuale:

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
sto cercando di implementare processore personalizzato da utilizzare PollingConsumer con i nomi di file dinamici:

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

Ora ritorna contenuto del file su prima risposta, ma su ogni richiesta successiva ho ricevuto il ciclo eterno dei messaggi di registro sopra:

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

UPD4
Ho implementato il percorso dinamico che viene aggiunto prima dell'elaborazione e rimosso dopo di esso. Questo metodo è descritto nel post this nel forum Apache Camel. Il percorso utilizza il processore sopra per consumare il file. Il risultato è lo stesso

risposta

9

Il modo semplice è spesso il modo migliore. Mi rifiuto di trattare con il componente di file Apache Camel in questo caso e implementato seguendo processore:

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

Ora sta funzionando come un fascino

+0

può mostrare ciò che il DSL assomiglia utilizzando il processore personalizzato? C'è un modo per passare un processore personalizzato a pollEnrich? – pimlottc