我有多个客户端将文件发送到服务器。对于一组数据,有两个文件包含有关该数据的信息,每个文件具有相同的名称。收到文件后,服务器会向我的队列发送一条消息,其中包含文件路径,文件名,客户端ID以及文件的“类型”(都有相同的文件扩展名,但有两种“类型, “称他们为A和B)。
一组数据的两个文件具有相同的文件名。一旦服务器收到这两个文件,我就需要启动一个将两者结合起来的程序。目前我有一些看起来像这样的东西:
from("jms:queue.name").aggregate(header("CamelFileName")).completionSize(2).to("exec://FILEPATH?args=");
我遇到的是标题(“CamelFileName”),更具体地说是聚合器的工作方式。
如果将completionSize设置为2,它是否只是吸收所有消息并将它们存储在某些数据结构中,直到与第一条消息匹配的第二条消息通过?此外,header()是否期望一个特定的值?我有多个客户端,所以我想在标题中有客户端ID和文件名,但我再次不知道是否必须给出一个特定的值。我也不知道我是否可以使用正则表达式。
任何想法或提示都会非常有用。 感谢
编辑: 这是我现在的一些代码。根据我对这里问题的描述以及对所选答案的评论,它看起来是否准确(除了我没有复制的括号内)?
public static void main(String args[]) throws Exception{
CamelContext c = new DefaultCamelContext();
c.addComponent("activemq", activeMQComponent("vm://localhost?broker.persistent=false"));
//ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
//c.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
c.addRoutes(new RouteBuilder() {
public void configure() {
from("activemq:queue:analytics.camelqueue").aggregate(new MyAggregationStrategy()).header("subject").completionSize(2).to("activemq:queue:analytics.success");
}
});
c.start();
while (true) {
System.out.println("Waiting on messages to come through for camel");
Thread.sleep(2 * 1000);
}
//c.stop();
}
private static class MyAggregationStrategy implements AggregationStrategy {
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
if (oldExchange == null)
return newExchange;
// and here is where combo stuff goes
String oldBody = oldExchange.getIn().getBody(String.class);
String newBody = newExchange.getIn().getBody(String.class);
boolean oldSet = oldBody.contains("set");
boolean newSet = newBody.contains("set");
boolean oldFlow = oldBody.contains("flow");
boolean newFlow = newBody.contains("flow");
if ( (oldSet && newFlow) || (oldFlow && newSet) ) {
//they match so return new exchange with info so extractor can be started with exec
String combined = oldBody + "\n" + newBody + "\n";
newExchange.getIn().setBody(combined);
return newExchange;
}
else {
// no match so do something....
return null;
}
}
}
答案 0 :(得分:3)
您必须提供AggregationStrategy来定义您想要如何组合Exchange ......
如果您只对fileName感兴趣并且只接收2个Exchange,那么您可以使用UseLatestAggregationStrategy来通过最新的Exchange一次2已经'聚合'...
说,听起来你需要保留两个Exchange(每个clientId一个),这样你就可以将这些信息传递给'exec'步骤......如果是这样,你可以把Exchange组合成一个GroupedExchange持有者使用通过groupExchanges
选项启用的内置聚合策略...或特定的自定义AggregationStrategy来组合它们,但是你喜欢。只需要记住,你的'exec'步骤需要处理你决定使用的任何聚合结构......
参见这些单元测试的例子: