我需要实现由多个步骤组成的集成流程,其中每个步骤都可以由可变数量的处理器(插件)执行。
到目前为止我所拥有的:
<!-- gateway -->
<int:gateway default-request-channel="step/1" service-interface="ServiceGateway">
<int:method name="send" />
</int:gateway>
<!-- plugin 1 -->
<int:publish-subscribe-channel id="step/1" apply-sequence="true" />
<int:service-activator input-channel="step/1" output-channel="step/2">
<bean class="Transformer" />
</int:service-activator>
<int:service-activator input-channel="step/1" output-channel="step/2">
<bean class="Transformer2" />
</int:service-activator>
<!-- plugin 2 -->
<int:publish-subscribe-channel id="step/2" apply-sequence="true" />
<int:service-activator input-channel="step/2" output-channel="end">
<bean class="Transformer3" />
</int:service-activator>
<int:service-activator input-channel="step/2" output-channel="end">
<bean class="HttpTransformer4" />
</int:service-activator>
<!-- aggregation -->
<int:channel id="end" />
<int:aggregator input-channel="end" />
预期的行为如下:
一切正常,但结果不是预期的,我只收到2个(随机)项而不是4个。
我认为问题是聚合器仅在两个项之后触发释放,因为“step / 2”通道中的“apply-sequence”会覆盖“step / 1”中的“apply-sequence”。所以问题是:如何让聚合器等待所有消息?
提前谢谢。
自定义发布策略:
@SuppressWarnings("unchecked")
@Override
public boolean canRelease ( MessageGroup group ) {
MessageHeaders headers = group.getOne ().getHeaders ();
List<List<Object>> sequenceDetails = (List<List<Object>>) headers.get ( "sequenceDetails" );
System.out.println ( sequenceDetails );
int expectedSize = 1;
//map message id, max group size reached (i.e. sequenceNumber==sequenceSize)
for ( List<Object> sequenceItem : sequenceDetails ) {
if ( sequenceItem.get ( 1 ) != sequenceItem.get ( 2 ) ) {
System.err.println ( "--> AGG: no release check, group max not reached" );
return false;
}
expectedSize *= (int) sequenceItem.get ( 2 );//multiplies the group sizes
}
int expectedSize2 = expectedSize * (int) headers.get ( "sequenceSize" );
int currentSize = group.getMessages ().size () * expectedSize;
System.err.println ( "--> AGG: " + expectedSize2 + " : " + currentSize );
boolean canRelease = expectedSize2 == currentSize;
if ( canRelease ) {
System.out.println ( "ok" );
}
return canRelease;
}
打印出来:
[[7099b583-55d4-87d3-4502-993f05bfb388,1,2]]
- &GT; AGG:没有发布检查,未达到最大组
[[7099b583-55d4-87d3-4502-993f05bfb388,1,2]]
- &GT; AGG:没有发布检查,未达到最大组
[[7099b583-55d4-87d3-4502-993f05bfb388,2,2]]
- &GT;阿格:4:2
[[7099b583-55d4-87d3-4502-993f05bfb388,2,2]]
- &GT;阿格:4:4
汇总代码:
@Aggregator
public Object aggregate ( List<Message<?>> objects ) {
List<Object> res = new ArrayList<> ();
for ( Message<?> m : objects ) {
res.add ( m.getPayload () );
MessageHeaders headers2 = m.getHeaders ();
System.out.println ( headers2.get ( "history" ) );
}
return res;
}
打印出来:
gateway2,core-channel,(内部bean)#57018165,async / step / 1,core-channel,(内部bean)#57018165,async / step / 2,core-channel,(内部bean)#57018165, END2
gateway2,core-channel,(内部bean)#57018165,async / step / 1,core-channel,(内部bean)#57018165,async / step / 2,core-channel,(内部bean)#57018165, END2
[102,202] - &gt;最终结果列表,预计将由4个项目组成
答案 0 :(得分:1)
使用自定义发布策略。来自第一个pubsub的关联数据被第二个pubsub推送到sequenceDetails
标题中的堆栈。
修改强>
问题是有两组;你需要关联初始correlationId。这是一个纯粹的SpEL解决方案;使用自定义关联/释放策略来确保数据符合预期(并使用getOne()
而不是迭代器)可能更安全... ...
<int:aggregator input-channel="end2"
correlation-strategy-expression=
"headers['sequenceDetails'][0][0]"
release-strategy-expression=
"size() == iterator().next().headers['sequenceSize'] * iterator().next().headers['sequenceDetails'][0][2]" />