Apache camel 驼峰休息DSL-聚合策略奇怪的行为

Apache camel 驼峰休息DSL-聚合策略奇怪的行为,apache-camel,Apache Camel,标题有点像拉票者,如果它不起作用,当然是我的错,因为它应该起作用 from("direct:aggregate").routeId("aggregate") .log("route : ${routeId}") .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy()) .completionPredicate(new Cu

标题有点像拉票者,如果它不起作用,当然是我的错,因为它应该起作用

    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));
我想执行从rdbms到solr和mongo db的数据传输。 为此,我必须完成以下步骤(例如):

    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));
  • 获取要转移的客户ID
  • 获取客户的详细信息
  • 获取客户发票
  • 向客户付款
然后,聚合并保存到mongo db和solr以进行索引

    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));
这是我的代码,但我无法让它工作:

from("seda:initial-data-transfer")
        .setProperty("recipientList", simple("direct:details,direct:invoices,direct:payments"))
        .setProperty("afterAggregate", simple("direct:mongodb,direct:solr"))
        .setBody(constant("{{query.initial-data-transfer.ids}}"))
        .to(jdbc)
        .process(new RowSetIdsProcessor())
        .split().tokenize(",", 1000) // ~200k ids - group by 1000 ids
        .to("direct:customers-ids");

from("direct:customers-ids")
        .recipientList(exchangeProperty("recipientList").tokenize(","))
        // ? .aggregationStrategy(new CustomerAggregationStrategy()).parallelProcessing()
        .aggregate(header("CamelCorrelationId"), new CustomerAggregationStrategy())             
        .completionPredicate(new CustomerAggregationPredicate()) // true if details + invoices + payments, etc ....
        // maybe a timeOut here ?
        .process(businessDataServiceProcessor)
        .recipientList(exchangeProperty("afterAggregate").tokenize(","));

from("direct:details")
        .setHeader("query", constant("{{query.details}}"))
        .bean(SqlTransform.class,"detailsQuery").to(jdbc)
        .process(new DetailsProcessor());

from("direct:invoices")
        .setHeader("query", constant("{{query.invoices}}"))
        .bean(SqlTransform.class,"invoicessQuery").to(jdbc)
        .process(new InvoicesProcessor());
    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));
我不明白聚合策略是如何工作的。 有时,我可以执行2或3个1000个ID的块,并保存到mongo DB和Solr,但之后,aggregationStrategy中的所有交换都是空的

    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));
我试了很多想法。。但每次聚合都会失败

    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));
谢谢你的帮助

    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));
更新:

    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));
以下是CustomerAggregationStrategy的一部分:

public class CustomerAggregationStrategy implements AggregationStrategy {
    @Override
    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
        Message newIn = newExchange.getIn();

        CustomerDataCollector collector = null;
        if (oldExchange == null) {
            int completionSize = newExchange.getProperty("completionSize", Integer.class);
            collector = new CustomerDataCollector(completionSize);
            CollectData(collector, newIn, newExchange);
            newIn.setBody(collector);
            return newExchange;
        }
        collector = oldExchange.getIn().getBody(CustomerDataCollector.class);
        CollectData(collector, newIn, newExchange);
        return oldExchange;
    }

    private void CollectData(CustomerDataCollector collector, Message message, Exchange exchange) {
        String recipientListEndpoint = (String)exchange.getProperty(Exchange.RECIPIENT_LIST_ENDPOINT);
        switch (recipientListEndpoint){
            case "direct://details" :
                collector.setDetails(message.getBody(Map.class));
                break;
            case "direct://invoices" :
                collector.setInvoices(message.getBody(Map.class));
                break;
            case "direct://payments" :
                collector.setPayments(message.getBody(Map.class));
                break;
        }
    }
}
String camelCorrelationId = (String)exchange.getProperty(Exchange.CORRELATION_ID);

[t-AggregateTask] .i.c.a.CustomerAggregationStrategy : CustomerAggregationStrategy.CollectData : direct://details  ID-UC-0172-50578-1484523575668-0-5
[t-AggregateTask] .i.c.a.CustomerAggregationStrategy : CustomerAggregationStrategy.CollectData : direct://invoices ID-UC-0172-50578-1484523575668-0-5
[t-AggregateTask] .i.c.a.CustomerAggregationStrategy : CustomerAggregationStrategy.CollectData : direct://payments ID-UC-0172-50578-1484523575668-0-5
    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));
更新:

    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));
我可以将此记录在CustomerAggregationStrategy中:

public class CustomerAggregationStrategy implements AggregationStrategy {
    @Override
    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
        Message newIn = newExchange.getIn();

        CustomerDataCollector collector = null;
        if (oldExchange == null) {
            int completionSize = newExchange.getProperty("completionSize", Integer.class);
            collector = new CustomerDataCollector(completionSize);
            CollectData(collector, newIn, newExchange);
            newIn.setBody(collector);
            return newExchange;
        }
        collector = oldExchange.getIn().getBody(CustomerDataCollector.class);
        CollectData(collector, newIn, newExchange);
        return oldExchange;
    }

    private void CollectData(CustomerDataCollector collector, Message message, Exchange exchange) {
        String recipientListEndpoint = (String)exchange.getProperty(Exchange.RECIPIENT_LIST_ENDPOINT);
        switch (recipientListEndpoint){
            case "direct://details" :
                collector.setDetails(message.getBody(Map.class));
                break;
            case "direct://invoices" :
                collector.setInvoices(message.getBody(Map.class));
                break;
            case "direct://payments" :
                collector.setPayments(message.getBody(Map.class));
                break;
        }
    }
}
String camelCorrelationId = (String)exchange.getProperty(Exchange.CORRELATION_ID);

[t-AggregateTask] .i.c.a.CustomerAggregationStrategy : CustomerAggregationStrategy.CollectData : direct://details  ID-UC-0172-50578-1484523575668-0-5
[t-AggregateTask] .i.c.a.CustomerAggregationStrategy : CustomerAggregationStrategy.CollectData : direct://invoices ID-UC-0172-50578-1484523575668-0-5
[t-AggregateTask] .i.c.a.CustomerAggregationStrategy : CustomerAggregationStrategy.CollectData : direct://payments ID-UC-0172-50578-1484523575668-0-5
    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));
CamelCorrelationId的值与预期值相同。 我想CamelCorrelationId是正确的。是吗?

好的,现在好多了

    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));
在tokeniszer之后,我像这样设置属性CustomCorrelationId

    .split().tokenize(",", 1000)
    .setProperty("CustomCorrelationId",header("breadcrumbId"))
    .to("direct:customers-ids")
    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));
并在此值上进行如下聚合:

    from("direct:customers-ids")
            .recipientList(exchangeProperty("recipientList").tokenize(","))

    from("direct:details")
            .setHeader("query", constant("{{query.details}}"))
            .bean(SqlTransform.class,"detailsQuery").to(jdbc)
            .process(new DetailsProcessor())
            .to("direct:aggregate");      
    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));

    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));
这项工作现在很好,数据已正确聚合。谢谢你的帮助。
您指出了方向。

如何设置标题
CamelCorrelationId
?相关性表达式必须是您在交换之间的共同点,我认为CorrelationId总是不同的,那么它就不会像这样工作。。。。如果您可以为CustomerAggregationStrategy类添加代码(或至少提及逻辑),这将有助于更好地解决路由问题。我不会根据以下内容设置CamelCorrelationID:“某些EIP模式将派生一个子消息,在这些情况下,Camel将在Exchange上添加一个相关id,作为其键Exchange.correlation_id的属性,该键链接回源Exchange。例如,拆分器、多播、收件人列表和有线点击EIP就是这样做的。”。RecipientList EIP就是这样做的。我用一些代码更新了这个问题。谢谢你的帮助。是的,那么它将永远不会聚合,因为所有邮件的correlationId都不同。首先,你必须定义“公共密钥”“您将在其上聚合,然后,该策略定义如何合并两个聚合的消息。例如,如果您希望聚合每个客户的所有消息,那么correlationExpression必须类似于
头(customerId)
@ruff查看日志。CamelCorrelationId是相同的。这是巧合吗?
    from("direct:aggregate").routeId("aggregate")
            .log("route : ${routeId}")
            .aggregate(property("CustomCorrelationId"), new CustomAggregationStrategy())
            .completionPredicate(new CustomerAggregationPredicate())
            .process(businessDataServiceProcessor)
            .recipientList(exchangeProperty("afterAggregate").tokenize(","));