在尝试使用Apache骆驼聚合策略时,我遇到了如下所述的问题:
我的应用程序:公开了一个简单的肥皂服务,它接受组织中各部门的名称(财务,销售......)。在我的骆驼路线中,我将请求相应地路由到部门特定路线。在这些路由中,我查询一个表,并获取该部门的员工。
作为对soap服务的回应,我想将所有员工汇总在一起并发送。
以下是我的骆驼路线:
<camelContext id="camel"
xmlns="http://camel.apache.org/schema/spring">
<camel:dataFormats>
<camel:jaxb contextPath="org.example.departments" id="jaxb"/>
</camel:dataFormats>
<route id="simple-route">
<!-- <camel:to id="unmarshallDeps" uri="bean:departmentProcessor"></camel:to> -->
<from id="_from1" uri="cxf:bean:departmentsEndpoint?dataFormat=PAYLOAD&loggingFeatureEnabled=true"/>
<camel:unmarshal id="_unmarshal1" ref="jaxb"/>
<camel:setHeader headerName="departments" id="_setHeader1">
<camel:method method="getDepartmentRoute" ref="depRouter"/>
</camel:setHeader>
<camel:recipientList id="_recipientList1">
<camel:header>departments</camel:header>
</camel:recipientList>
<camel:log id="_log1" message="Body in original cxf after aggregation ******** ${body} and exchange id is ${exchangeId}"/>
</route>
<camel:route id="_route1">
<camel:from id="_from2" uri="direct:finance"/>
<camel:to id="_to1" uri="mySqlComponent:select id,Location,Head,email,create_date from finance"/>
<camel:to id="_to2" pattern="InOut" uri="seda:departmentAggregator"/>
</camel:route>
<camel:route id="_route2">
<camel:from id="_from3" uri="direct:sales"/>
<camel:to id="_to3" uri="mySqlComponent:select id,Location,Head,email,create_date from sales"/>
<camel:to id="_to4" pattern="InOut" uri="seda:departmentAggregator"/>
</camel:route>
<camel:route id="_route3">
<camel:from id="_from4" uri="direct:hr"/>
<camel:to id="_to5" uri="mySqlComponent:select id,Location,Head,email,create_date from hr"/>
<camel:to id="_to6" pattern="InOut" uri="seda:departmentAggregator"/>
</camel:route>
<camel:route id="_route4">
<camel:from id="_from5" uri="seda:departmentAggregator"/>
<camel:aggregate completionSize="2" id="_aggregate1" strategyRef="myAggregator">
<camel:correlationExpression>
<camel:constant>Constant</camel:constant>
</camel:correlationExpression>
<camel:log message="Aggregated Body : ${body} and exchange id is ${exchangeId}"></camel:log>
<!-- <camel:marshal id="_marshal1" ref="jaxb"/> -->
<!-- <camel:setBody id="_setBody1">
<camel:simple>${body}</camel:simple>
</camel:setBody> -->
</camel:aggregate>
<camel:log id="_log4" message="Body outside aggregate : ${body} and exchange id is ${exchangeId}"/>
</camel:route>
</camelContext>
现在,我注意到在聚合体内打印的主体确实是一个包含所有员工的聚合体,但是当我在聚合体外打印身体时,它会打印最新的交换而不是聚合交换。以下是我的聚合策略:
public Exchange aggregate(Exchange oldExchange, Exchange newExchange)
{
ArrayList<Map<String, Object>> depList = newExchange.getIn().getBody(ArrayList.class);
int depCount = depList.size();
System.out.println("Department Count is : " + depCount);
if (oldExchange == null) {
for (int i = 0; i < depCount; i++) {
Map<String, Object> row = (Map) depList.get(i);
Department newDepartment = new Department();
newDepartment.setLocation((String) row.get("Location"));
newDepartment.setHead((String) row.get("Head"));
newDepartment.setEmail((String) row.get("email"));
departments.getDepartment().add(newDepartment);
}
newExchange.getIn().setBody(departments);
return newExchange;
} else {
System.out.println("New Exchange: Department Count is : " + depCount);
departments = oldExchange.getIn().getBody(Departments.class);
System.out.println("Aggregate Department count : " + departments.getDepartment().size());
for (int j = 0; j < depCount; j++) {
Map<String, Object> row = (Map) newExchange.getIn().getBody(ArrayList.class).get(j);
Department newDepartment = new Department();
newDepartment.setLocation((String) row.get("Location"));
newDepartment.setHead((String) row.get("Head"));
newDepartment.setEmail((String) row.get("email"));
departments.getDepartment().add(newDepartment);
}
newExchange.getIn().setBody(departments);
oldExchange.getIn().setBody(departments);
}
// System.out.println("exchange is out capable ? : " +
// newExchange.getPattern().isOutCapable());
return oldExchange;
}
答案 0 :(得分:0)
聚合策略通常可以无缝嵌入到EIP中;你不必手动调用它,Camel会为你做。
recipientList 正是接受聚合策略作为参数的那些EIP之一。 请参阅example in Camel doc。
因此,您的&#34; seda:departmentAggregator&#34; 路线实际上并不需要(以及&#34;直接:[部门]的所有呼叫) &#34; 路线)。相反,其内容应+/-包含在 recipientList 定义中。