Spring integration spring集成:多步多通道订户

Spring integration spring集成:多步多通道订户,spring-integration,Spring Integration,我需要实现由多个步骤组成的集成流,其中每个步骤都可以由不同数量的处理器(插件)执行 到目前为止,我所拥有的: <!-- gateway --> <int:gateway default-request-channel="step/1" service-interface="ServiceGateway"> <int:method name="send" /> </int:gateway> <!-- plugin 1 -->

我需要实现由多个步骤组成的集成流,其中每个步骤都可以由不同数量的处理器(插件)执行

到目前为止,我所拥有的:

<!-- 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个“step/1”插件处理
  • “步骤/1”插件的每个输出都由“步骤/2”插件处理
  • 聚合器应聚合4项(1->2->4)
  • 一切正常,但结果不是预期的,我只收到2个(随机)项目,而不是4个

    我认为问题在于聚合器仅在两项之后触发发布,因为“步骤/2”通道中的“应用序列”覆盖了“步骤/1”中的“应用序列”。所以问题是:如何让聚合器等待所有消息

    先谢谢你

    自定义发布策略:

    @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;
    }
    
    @SuppressWarnings(“未选中”)
    @凌驾
    公共布尔canRelease(MessageGroup组){
    MessageHeaders=group.getOne().getHeaders();
    List sequenceDetails=(List)headers.get(“sequenceDetails”);
    System.out.println(序列详细信息);
    int expectedSize=1;
    //映射消息id,达到的最大组大小(即sequenceNumber==sequenceSize)
    用于(列表序列项:序列详细信息){
    if(sequenceItem.get(1)!=sequenceItem.get(2)){
    System.err.println(“-->AGG:无发布检查,未达到组最大值”);
    返回false;
    }
    expectedSize*=(int)sequenceItem.get(2);//乘以组大小
    }
    int expectedSize2=expectedSize*(int)headers.get(“sequenceSize”);
    int currentSize=group.getMessages().size()*expectedSize;
    System.err.println(“-->AGG:+expectedSize2+”:“+currentSize”);
    布尔值canRelease=expectedSize2==currentSize;
    如果(可以发布){
    System.out.println(“正常”);
    }
    返回和释放;
    }
    
    打印出:

    [[7099b583-55d4-87d3-4502-993f05bfb388,1,2]]

    -->AGG:未进行释放检查,未达到组最大值

    [[7099b583-55d4-87d3-4502-993f05bfb388,1,2]]

    -->AGG:未进行释放检查,未达到组最大值

    [[7099b583-55d4-87d3-4502-993f05bfb388,2,2]]

    -->澳大利亚:4:2

    [[7099b583-55d4-87d3-4502-993f05bfb388,2,2]]

    -->澳大利亚: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;
    }
    
    聚合器 公共对象聚合(列表m:对象){ res.add(m.getPayload()); MessageHeaders-headers2=m.getHeaders(); System.out.println(headers2.get(“历史”); } 返回res; } 打印出:

    网关2,核心通道,(内部bean)#5701865,异步/step/1,核心通道,(内部bean)#5701865,异步/step/2,核心通道,(内部bean)#5701865,end2

    网关2,核心通道,(内部bean)#5701865,异步/step/1,核心通道,(内部bean)#5701865,异步/step/2,核心通道,(内部bean)#5701865,end2


    [102202]-->最终结果列表,预计由4项组成

    使用自定义发布策略。来自第一个pubsub的相关数据由第二个pubsub推送到
    sequenceDetails
    标题中的堆栈上

    编辑

    问题是有两个群体;您需要在初始correlationId上进行关联。这是一个纯SpEL溶液;使用自定义关联/发布策略来确保数据符合预期可能更安全(并使用
    getOne()
    而不是迭代器)

    
    
    Hi Gary,我已经实施了自定义发布策略,现在按照顺序(4)中正确的项数触发发布。现在的问题是,输出仍然由2项组成。实现自定义聚合器我已经看到,即使发布策略触发了4个项目的发布,聚合方法(在4条消息通过canRelease方法后正确调用)也会收到一个包含2个项目的消息列表(仅两个生成的组中的一个)。这对我来说没有任何意义;如果发布策略看到一个包含4条消息的组,那么您将得到所有4条消息。你的评论
    只有两个发布组中的一个
    让我困惑;应该有一个包含4条消息的组(尽管
    sequenceSize
    sequenceNumber
    标题是假的)。你能展示你的
    发布策略吗?(编辑您的问题,不要试图将其粘贴到评论中)。我添加了发布策略和聚合的两种方法这看起来是错误的
    int currentSize=group.getMessages().size()*expectedSize-我想你只需要像
    return group.size()==sequenceSize*nestedSequenceSize
    这样的东西。我在上面发布了测试代码
    <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]" />