1

HTTP 経由で 1 つのファイルをダウンロードする必要があるルートがあります。

このルートは、コマンドを含むメッセージ (HTTP リソースの URL と、それを保存するローカル ファイルの URI を含む) を受信したときに動的に追加され、ファイル転送が完了したらルートを削除したいので、Camel を使用しますプロトコル トランスレータとしてのみ。

これには Camel を使用しています。これは、このルートが EIP 上に構築されたプロジェクトに該当するためです。このプロジェクトでは、メッセージングと統合のために Camel があらゆる場所で使用されています。

私が使用した:

onCompletion().setBody(simple("")).bean(new Stop(getContext(), transferID));

from("stream:url?url="+from).to("stream:file?fileName="+to).routeId(this.transferID);

(ファイルは大きく、10 ~ 100 Gb です)

ファイル全体が転送される前に発生することがわかりonCompletionます。実際には、100〜300 kBなど、予測できない量のバイトのみが転送されます。

「ストリーム」とonCompletion互換性がないか、何か間違っていますか?

編集:私がやっているBeanで:

c.stopRoute(transferID);
c.removeRoute(transferID);
4

1 に答える 1

4

ストリーム コンポーネント は、ファイルの各行に対して新しい交換を作成します。

ストリーム コンポーネントは、XX 行 (デフォルトでは 0) で分割するオプションを提供します。

groupLines 0 Camel 2.5: コンシューマーで X 行のグループ化。たとえば、10 行をグループ化して、行ごとに 1 つの Exchange ではなく、10 行の Exchange のみを吐き出すには。

このオプションは、XX 行の新しい交換を作成するために使用されます。StreamConsumerの関連コードは次のとおりです。

 if (lines.size() >= endpoint.getGroupLines()) {
      // spit out lines
      Exchange exchange = endpoint.createExchange();

      // create message with the lines
      Message msg = new DefaultMessage();
      List<String> copy = new ArrayList<String>(lines);
      msg.setBody(endpoint.getGroupStrategy().groupLines(copy));
      exchange.setIn(msg);

      // clear lines
      lines.clear();

      getProcessor().process(exchange);
 }

そして、交換が完了するたびに onCompletion が実行されます

camel doc から ( onCompletion documentation ):

常に、成功して完了した場合のみ、または失敗した場合にのみトリガーされます

したがって、最初の行が読み取られた後、コードはルートを停止します

明らかに、ストリーム コンポーネントでファイルの終わりがいつ発生するかを知る方法は実際にはありません。

良い方法は、スプリッターのように CamelSplitComplete プロパティを持つことです。そのように使用できます ( onCompletion with onWhen 述語の章を参照):

onCompletion()
  .onWhen(property("CamelSplitComplete").isEqualTo("true"))
  .setBody(simple("")).bean(new Stop(getContext(), transferID));

編集:ストリーム コンシューマーのみを探していましたが、プロデューサーも使用しているためです。closeOnDone プロパティを見てください。うまくいくかもしれません。

closeOnDone | 偽 | Camel 2.11.0: このオプションは、Splitter および同じファイルへのストリーミングと組み合わせて使用​​されます。アイデアは、パフォーマンスを向上させるために、ストリームを開いたままにし、スプリッターが完了したときにのみ閉じることです。これには、2 つ以上のファイルではなく、同じファイルにのみストリーミングする必要があることに注意してください。

于 2013-10-22T08:16:14.620 に答える