Apache Camel Aggegation战略

时间:2018-04-10 14:55:49

标签: apache-camel

在尝试使用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&amp;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;
}

1 个答案:

答案 0 :(得分:0)

聚合策略通常可以无缝嵌入到EIP中;你不必手动调用它,Camel会为你做。

recipientList 正是接受聚合策略作为参数的那些EIP之一。 请参阅example in Camel doc

因此,您的&#34; seda:departmentAggregator&#34; 路线实际上并不需要(以及&#34;直接:[部门]的所有呼叫) &#34; 路线)。相反,其内容应+/-包含在 recipientList 定义中。