2017-02-07 23 views
0

私の要件は次のとおりです。ファイルを解凍し、解凍したxmlファイルからメタデータ情報を読み取る必要があります。これはxmlToObjectMapperで行われます。今私はzipファイル内にある複数の他のXMLからのデータでメタデータを豊かにする必要があります。つまり、それらを解凍して、MetadataHolderオブジェクトに情報を添付する必要があります。私はこれをコメント行のpollEnrichに実装したかったのです。複数ファイルI/O with apache camel

from("file://{{first.directory}}?noop=true&idempotent=true") 
     .split(new ZipSplitter()) 
      .streaming() 
       .choice() 
        .when(header("zipFileName").isEqualTo("metadata.xml")) 
         .multicast() 
          .to("file://{{first.directory}}/Working?fileName=$simple{file:onlyname.noext}/${header.zipFileName}") 
          .pipeline() 
           .convertBodyTo(String.class, StandardCharsets.ISO_8859_1.name()) 
           .bean("xmlToObjectMapper", "readAllRequiredMetadata") 
           //.pollEnrich("", 0, new MetadataHolderAggregationStrategy()) 
          .end() 
         .end() 
       .end() 
      .to("file://{{first.directory}}/Working?fileName=$simple{file:onlyname.noext}/${header.zipFileName}") 
     .end() 
    .end() 
    ; 

しかし、私は、次のスタックトレースを取得するので、今、私は立ち往生しています:

org.apache.camel.InvalidPayloadException: No body available of type: java.lang.String but has value: [email protected]4b of type: org.apache.camel.dataformat.zipfile.ZipInpu 
tStreamWrapper on: Message[id]. Caused by: Error during type conversion from type: java.lang.String to the required type: java.lang.String with value [Body is instance of java.io.I 
nputStream] due java.io.IOException: Stream closed. Exchange[id]. Caused by: [org.apache.camel.TypeConversionException - Error during type conversion from type: java.lang.String to 
the required type: java.lang.String with value [Body is instance of java.io.InputStream] due java.io.IOException: Stream closed] 
私は、マルチキャストが暗黙的にストリームをキャッシュし、すべてのエンドポイントに送信することを考え

...

そうすることができます誰がなぜこれが起こっているのか教えてください。要件の私のソリューションは有効な方法ですか、要件を複数のルートに分割する必要がありますか?

EDIT1:

私はルートに.streamCaching()を追加することによって、例外を除いて問題を解決しました。他の問題のため、私は元のルートを少し変更しなければなりませんでした。

from("file://{{first.directory}}?noop=true&idempotent=true") 
     .streamCaching() 
     .split(new ZipSplitter()) 
      .streaming() 
       .choice() 
        .when(header("zipFileName").isEqualTo("metadata.xml")) 
         .multicast() 
          .to("file://{{first.directory}}/Working?fileName=$simple{file:onlyname.noext}/${header.zipFileName}") 
          .pipeline() 
           .convertBodyTo(String.class, StandardCharsets.ISO_8859_1.name()) 
           .bean("xmlToObjectMapper", "readAllRequiredMetadata") 
           .pollEnrich("file://{{second.directory}}?&noop=true&idempotent=true", 0, new MetadataHolderAggregationStrategy()) 
          .end() 
         .end() 
        .endChoice() 
        .otherwise() 
         .to("file://{{first.directory}}/Working?fileName=$simple{file:onlyname.noext}/${header.zipFileName}") 
       .end() 
     .end() 
    .end() 
    ; 

しかし、今私はpollEnrichに問題があります。私のMetadataHolderAggregationStrategyのnewExchangeは常にnullです。これをどうすれば解決できますか?

EDIT2:

は最終的に私は解決策を見つけました。私はpollEnrichの代わりにenrichを使用し、java(readAllRequiredMetadata2)で全体I/Oを実装しなければなりませんでした。私の最終的な解決策は次のようになります:

from("file://{{first.directory}}?noop=true&idempotent=true") 
     .streamCaching() 
     .split(new ZipSplitter()) 
      .streaming() 
       .choice() 
        .when(header("zipFileName").isEqualTo("metadata.xml")) 
         .multicast() 
          .to("file://{{first.directory}}/Working?fileName=$simple{file:onlyname.noext}/${header.zipFileName}") 
          .pipeline() 
           .convertBodyTo(String.class, StandardCharsets.ISO_8859_1.name()) 
           .bean("xmlToObjectMapper", "readAllRequiredMetadata") 
           .enrich("direct:readResources", 0, new MetadataHolderAggregationStrategy()) 
           //Go on processing the enriched metadata 
          .end() 
         .end() 
        .endChoice() 
        .otherwise() 
         .to("file://{{first.directory}}/Working?fileName=$simple{file:onlyname.noext}/${header.zipFileName}") 
       .end() 
     .end() 
    .end() 
    ; 

from("direct:readResources") 
    .bean("xmlToObjectMapper", "readAllRequiredMetadata2") 
.end() 
; 

答えて

0

ストリームのようなデータの場合は、おそらくストリームキャッシュを使用する必要があります。これはデフォルトではオフになっているので、第2のエンドポイントは最初のエンドポイントによってすでに読み込まれているので、それを持たないでしょう。そこに詳細を確認することができます:http://camel.apache.org/stream-caching.html

+0

ストリームキャッシングのヒント – Kamikazzze