6

一部のリクエストに対してファイルを返すRESTfulサービス(CXFRSコンポーネントを使用)を実装しています。各ファイルは、その ID と拡張子、つまりrestfulservice.com/path/file/1/pdf. 一度追加された各ファイルは決して変更されません。フェッチ後にファイルを移動または削除してはならず、通常は同時にアクセスできる必要があります。これが私の 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)");

この構成の問題は、応答が 2 番目の (なぜ?) 要求に対してのみ空でない本文を持つことです。

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

Apace Camel のバージョンは 2.10.4 です

どんな助けでもいただければ幸いです

UPD1 : Content Enricherページに、「pollEnrich は現在の Exchange のデータにアクセスしていません」という
警告があります。しかし、ファイルの URLに追加しても何も変わりませんfileName=${body}

UPD2 : pollEnrich はURL ( link
) で指定された 動的をサポートしていないようです。現時点でのルート:fileName

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 フォーラムのこの投稿で説明されています。ルートは上記のプロセッサを使用してファイルを消費します。結果は同じです

4

1 に答える 1

9

多くの場合、単純な方法が最善の方法です。この場合、Apache Camel ファイル コンポーネントの処理を拒否し、次のプロセッサを実装しました。

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

今では魔法のように機能しています

于 2013-04-15T10:20:29.350 に答える