Spring integration spring集成-拆分器和聚合器

Spring integration spring集成-拆分器和聚合器,spring-integration,Spring Integration,目前,我正在为新应用程序与SpringIntegration合作,并启动了poc,以了解如何处理故障案例。 在我的应用程序中,spring integration将接收来自IBM mq的消息,并根据消息类型验证头信息和到不同队列的路由。传入的消息可能是批量消息,所以我使用了SpringIntegration中的拆分器和聚合器,并且在技术工作流程上取得了良好的进展和控制。 目前我面临的问题很少,我们有IBMMQ和webservice作为网关。两个网关都接收消息并发送到拆分器通道,其中拆分器拆分消息

目前,我正在为新应用程序与SpringIntegration合作,并启动了poc,以了解如何处理故障案例。 在我的应用程序中,spring integration将接收来自IBM mq的消息,并根据消息类型验证头信息和到不同队列的路由。传入的消息可能是批量消息,所以我使用了SpringIntegration中的拆分器和聚合器,并且在技术工作流程上取得了良好的进展和控制。 目前我面临的问题很少,我们有IBMMQ和webservice作为网关。两个网关都接收消息并发送到拆分器通道,其中拆分器拆分消息并发送到出站通道(执行器通道)。因此,消息将被并行发送到目的地,状态更新服务激活器将使用相同的通道以order=2接收消息并发送到聚合器。因此,为了它的良好实施

问题: 如果jms出站网关抛出我添加的advise as exception handler执行选项,它将发送到另一个service activator以将失败状态更新到DTO对象,并将具有与输出相同的聚合器通道,但在这种情况下,我不会在聚合器通道中接收消息,聚合器仅在愉快流中接收

我希望聚合出站成功消息和失败消息(其他服务激活器更新状态),然后需要将完整状态作为另一个出站或webservice中的响应发布到响应队列

我试图命令成功的ServiceActivator和失败错误处理程序ServiceActivator具有相同的通道,该通道是聚合器的输入通道,并且它不工作

感谢您的指导,继续执行此工作流程

使用Spring集成2.2.2

<channel id="inbound"/>
<channel id="splitterInChannel"/>

<channel id="splitterOutChannel">
<dispatcher task-executor="splitterExecutor"/>
</channel>          
<beans:bean id="splitterExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <beans:property name="corePoolSize" value="5" />
    <beans:property name="maxPoolSize" value="10" />
    <beans:property name="queueCapacity" value="25" />
</beans:bean>
<channel id="ValidatorChannel"/>

<channel id="outBoundjmsChannel"/>
<channel id="outBoundErrorChannel"/>
<channel id="finalOutputChannel"></channel>
<channel id="aggregatorChannel"/>

<jms:inbound-channel-adapter connection-factory="AMQConnectionFactory" 
destination="AMQueue" channel="inbound" auto-startup="true" 
extract-payload="false" acknowledge="transacted"></jms:inbound-channel-adapter>


<service-activator ref="InBoundProcessor" input-channel="inbound" output-channel="splitterInChannel"></service-activator>

<!-- splitter -->
<splitter ref="Splitter" method="splitInput" input-channel="splitterInChannel" output-channel="splitterOutChannel"/>
<!-- validator -->
<service-activator ref="Validator" method="validate" input-channel="splitterOutChannel" output-channel="ValidatorChannel"/>         

<!-- need to add enricher -->
<service-activator ref="Enricher" method="enrich" input-channel="ValidatorChannel" output-channel="outBoundjmsChannel"/>            

<!-- outbound gateway -->

<jms:outbound-channel-adapter channel="outBoundjmsChannel" connection-factory="AMQConnectionFactory" destination-name="outputQueue" 
message-converter="customMessageConvertor" order="1"  >

        <jms:request-handler-advice-chain>
            <beans:bean class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
                <beans:property name="retryTemplate" >
                    <beans:bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate">
                        <beans:property name="retryPolicy">
                            <beans:bean class="org.springframework.retry.policy.SimpleRetryPolicy">
                            <beans:property name="maxAttempts" value="2" />
                            </beans:bean>
                        </beans:property>
                    <beans:property name="backOffPolicy">
                        <beans:bean class="org.springframework.retry.backoff.FixedBackOffPolicy">
                        <beans:property name="backOffPeriod" value="1000" />
                        </beans:bean>
                        </beans:property>
                    </beans:bean>            
                </beans:property>
                <beans:property name="recoveryCallback">
                    <beans:bean class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer">
                        <beans:constructor-arg ref="outBoundErrorChannel" />
                    </beans:bean>
                </beans:property>

            </beans:bean>
        </jms:request-handler-advice-chain>
    </jms:outbound-channel-adapter>



<!-- outBound error processor -->           
<service-activator  ref="ErrorProcessor" method="errorHandling" input-channel="outBoundErrorChannel" output-channel="aggregatorChannel" />          
<!-- Post send processor -->
<service-activator  ref="PostProcessor" method="Postprocessing" input-channel="outBoundjmsChannel" output-channel="aggregatorChannel" order="2"/>           
<!-- aggregator -->
<aggregator ref="Aggregator" correlation-strategy-method="aggregateStrategy" input-channel="aggregatorChannel" output-channel="finalOutputChannel"
release-strategy-method="isRelease" method="aggregate" expire-groups-upon-completion="true"/>


<!-- final processor or responder -->
<service-activator ref="FinalProcessor" method="endProcessing" input-channel="finalOutputChannel"/>         

</beans:beans>

在上面的配置中,到目前为止,我已经将发布策略设置为false,将关联方法设置为空字符串。如果这样做有效,我将为批生成UUID,并将在拆分器中将UUID附加到Corrate

在调试上述配置时,我注意到出站错误通道receive每当试图发送到出站适配器时(在我的例子中,它发送两次)。我不想在一个应用程序中重新尝试,而在另一个应用程序中,它需要尝试重新发布消息。 在这两种情况下,我都希望在最终尝试聚合后将消息发送到出站错误通道,如果失败,我将在ErrorProcessor中将状态更新为failed to send

两个问题。 1.接收到重复的消息到通道,很难确定最后的失败或成功。 2.无法制定发布策略的逻辑,难以确定哪一个是重复的,以及是否成功

在上面的例子中,我找不到一种比较对象的通用方法,因为equals方法没有合适的属性进行比较,而且也不会 与布尔字段进行比较的正确方法

请帮助我解决此问题,以继续我的工作流设计和完成

非常感谢您指导我继续。 谢谢 克里斯S


目前

public Object errorHandling(Object object){
        OutBoundMessage outBoundMessage = null;
        if(object instanceof MessagingException){

            outBoundMessage =((MessagingException) object).getFailedMessage();
        }else{
            //TODO: log the message
        }

        return outBoundMessage;
    }




    public String aggregateStrategy(OutBoundMessage outBoundMessage){

        //TODO: get the UUID from outbound message and return 
        return "";
    }




public List<OutBoundMessage> splitter(InBoundMessage inBoundMessage){

        String[] message = inBoundMessage.getRawMessage().split(",");
        long uuid = java.util.UUID.randomUUID().getLeastSignificantBits();
        List<OutBoundMessage> outBoundMessagelist = new ArrayList<OutBoundMessage>();
        for (String string : message) {
            OutBoundMessage outBoundMessage = new outBoundMessage();
            outBoundMessage.setCorrelationID(uuid);
            outBoundMessagelist.add(outBoundMessage);
        }

    }
公共对象错误处理(对象){
OutBoundMessage OutBoundMessage=null;
if(MessaginException的对象实例){
outBoundMessage=((MessaginException)对象).getFailedMessage();
}否则{
//TODO:记录消息
}
返回外部消息;
}
公共字符串聚合策略(OutBoundMessage OutBoundMessage){
//TODO:从出站消息获取UUID并返回
返回“”;
}
公共列表拆分器(InBoundMessage InBoundMessage){
String[]message=inBoundMessage.getRawMessage().split(“,”);
long uuid=java.util.uuid.randomUUID().GetLeastSignificanBits();
List outBoundMessagelist=新建ArrayList();
for(字符串:消息){
OutBoundMessage OutBoundMessage=新的OutBoundMessage();
outBoundMessage.setCorrelationID(uuid);
outBoundMessagelist.add(outBoundMessage);
}
}
在以下方法中添加为默认值false以进行验证

public boolean isRelease(List<OutBoundMessage> outBoundMessage){
        //TODO: need to define condition for closing the list aggregation
        return false;
    }
public boolean isRelease(列出outBoundMessage){
//TODO:需要定义关闭列表聚合的条件
返回false;
}

请分享您的
ErrorProcessor
源代码。以及
相关策略方法=“聚合策略”

我想知道您如何处理那里的
ErrorMessage
,以及如何在
ErrorProcessor
之后从消息中恢复
correlationKey

不确定如何构建自己的
correlationKey
,但默认情况下
提供
applySequence=true
。因此,
相关详细信息
在每个拆分的消息中都可用,以便能够在以后进行聚合

对于
ErrorMessageSendingRecoverer
中的
ErrorMessage
,我建议您注意那里的
异常
负载
。它看起来像(从
ErrorMessageSendingRecoverer
源代码):

else if(!(MessaginException的最后一个可丢弃实例)){
lastThrowable=new MessaginException((消息)context.getAttribute(“消息”),
lastThrowable.getMessage(
else if (!(lastThrowable instanceof MessagingException)) {
        lastThrowable = new MessagingException((Message<?>) context.getAttribute("message"),
                lastThrowable.getMessage(), lastThrowable);
    }
....
messagingTemplate.send(new ErrorMessage(lastThrowable));