[英]Camel Splitter Parallel Processing Array List - Concurrency Access Issue
[英]Split a List of Lists with camel splitter
我創建了許多 ArrayLists 來保存要拆分為它們自己的實體的單獨實體的集合。 這些被添加到一個 ArrayList 然后推送到我嘗試拆分列表列表的交換。 我似乎無法拆分列表列表。
嘗試了 Splitter 的許多變體,包括令牌等。
List<String> serviceRecords = new ArrayList<String>(); //holds an assets collection
List<String> toRecords = new ArrayList<String>(); //holds all asset collections
在收集屬於一個組的項目后,它們被添加到一個 ArrayList 中。
serviceRecords.add(sb.toString());
添加完所有項目后,將列表添加到列表中。
toRecords.addAll(serviceRecords);
然后我將列表推送到交易所
exchange.getIn().setBody(toRecords);
然后是 XML 路線,它在嘗試不同的事情時處於混亂狀態。 沒有一個工作。 必須有一個技巧來拆分列表列表。
<route autoStartup="true" id="core.fleet.asset.splitterRoute">
<from id="_from4" uri="{{fileEnrichmentEndpoint}}"/>
<process id="_process4" ref="assetCollectorProcessor"/>
<process id="_process5" ref="fleetAssetSplitter"/>
<split id="FleetSplit"> <!-- strategyRef="tsAggregationStrategy" -->
<!-- <simple>${body}</simple> -->
<tokenize token="BLOCKMarker"/>
<log id="splitBody" message="Split Body: ${body}"/>
<to id="_splitOut" uri="{{fileSplitDestination}}/?fileName=GCMS_asset_${date:now:yyyyMMddhhmmss}.csv"/>
<!-- <process id="getName" ref="fleetAssetFileName"/> -->
<!-- <to id="_splitOut" uri="{{fileSplitDestination}}/?fileName=GCMS_asset_${date:now:yyyyMMdd}.csv"/> -->
</split>
<!-- <to id="_splitOut" uri="{{fileSplitDestination}}/?fileName=GCMS_asset_${date:now:yyyyMMdd}.csv"/> -->
<stop/>
</route>
從列表列表的拆分生成的多個文件。
您可以根據需要使用 JavaBean 來實現嵌套的 Splitter 邏輯。
如果標准的Splitter EIP不能做你想要的,你可以用一個 bean 告訴他如何拆分你的消息的有效負載。
因此,如果您將 Splitter 配置為使用您的自定義 bean
from("direct:split")
.log("Original body: ${body}")
.split().method(new SplitterBean(), "splitServiceRecords")
.log("Message part: ${body}")
.to("mock:end");
並且 bean 只是在結果列表中收集所有服務記錄(來自您的示例)
public List<String> splitServiceRecords(List<List<String>> body) {
List<String> collectedServiceRecords = new ArrayList<String>();
// iterate over List containing lists and add each item of
// the inner list to the Splitter result
for (List<String> serviceRecords : body) {
for (String serviceRecord : serviceRecords) {
collectedServiceRecords.add(serviceRecord);
}
}
return collectedServiceRecords;
}
列表列表將成為包含所有項目的單個列表,每個項目成為一條消息,由 Camel 進一步路由。
上面路由的日志輸出:
INFO: Original body: [[Foo, Bar, Baz], [Record, item, thing]]
...
INFO: Message part: Foo
INFO: Message part: Bar
INFO: Message part: Baz
INFO: Message part: Record
INFO: Message part: item
INFO: Message part: thing
我不知道天氣會刪除這個還是為了其他人的興趣而離開。
在發現我使用了錯誤的 List 方法 List.addAll() 而不是 List.add(object) 並進行了此更正后,我的不好,令人驚訝的是,一切都按預期的理論預期工作,在其領域內的一切都有效。
所以這很簡單。 您無需執行任何特殊操作即可拆分列表列表。 拆分器將遍歷列表並拆分出單個列表。 然后,您可以掌握這些列表並處理它們並轉發它們。 愚蠢的我認為成熟的 Camel Splitter EIP 表現得很奇怪,它正在做它應該做的事情。
這是最終結果。 (感謝 burki 和其他人的幫助)
<route autoStartup="true" id="core.fleet.asset.splitterRoute">
<from id="_from4" uri="{{fileEnrichmentEndpoint}}"/>
<process id="_process4" ref="assetCollectorProcessor"/>
<process id="_process5" ref="fleetAssetSplitter"/>
<split id="fs1">
<simple>${body}</simple>
<log id="lfs1" message="Original Body: ${body}"/>
<process id="pfs1" ref="fileSplitter" />
<to id="seda:fs1" uri="seda:fs1"/>
</split>
</route>
我將文件名隱藏在位置 -0- 的內部列表列表中,因此我們只需提取文件名,設置 CamelFileName,稍微處理數據並將其發送到交換。
log.info("File Splitter :: Start");
List<String> pl = (List<String>) exchange.getIn().getBody(List.class);
log.info("File Pay Load: " + pl);
fName = pl.get(0); //get file name
exchange.getIn().setHeader("CamelFileName", fName);
pl.remove(0);
log.debug("**** serviceRecords ****");
Iterator<String> pitr = pl.iterator();
while ( pitr.hasNext()) {
log.debug(pitr.next());
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(baos);
for (String record : pl) {
out.writeBytes(record + System.lineSeparator());
}
out.flush();
exchange.getIn().setBody(baos.toByteArray());
out.close();
log.info("File Splitter :: Finish");
您只需在 RouterBuilder 配置中拆分兩次
from("direct:split")
.split(body())
.split(body())
.log("Message part: ${body}")
.to("mock:end");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.