当前位置: 首页 > 知识库问答 >
问题:

DSL中出站网关出现故障时路由到错误信道

裴卓君
2023-03-14

我有以下Spring Integration JAva DSL代码:

    return flow -> flow.channel(INPUT_CHANNEL)
            .transform(customMapper, "mapFrom")
            .enrichHeaders(polarisPreCompSoapActionHeader())
            .route("headers.key",
                    subflowMapping -> subflowMapping
                            .subFlowMapping("value1", subflow -> subflow
                                    .handle(webserviceOutboundGateway,
                                            e -> e.advice(skipAdvice()))
                            )
            )
            .channel(OUTPUT_CHANNEL);

@Bean
public Advice skipAdvice() {
    ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
    advice.setFailureChannel(errorChannel());
    return advice;
}

WebServiceOutboundGateway创建为MarshallingWebServiceOutboundGateway的bean。

我试图实现的是,当SOAP错误到达时,将错误消息路由到错误通道。我认为我可以向处理程序添加一个建议,这个建议应该是ExpressionEvaluatingRequestHandlerAdvise,我可以在其中设置失败通道。因此,每当出站网关中抛出错误时,错误消息将被转发到错误通道。

2020-05-20 22:21:48,161 INFO  com.acme.Timing Thread=qtp14486859-12 MDC=16d7cc4c-c9da-449b-8bfa-504e6d81185d REQUEST COMPLETE : time[39]ms  message[ProcessTran] endpoint[http://localhost:8081/system-integration-service/service]
2020-05-20 22:21:48,161 DEBUG org.springframework.integration.transformer.ContentEnricher$Gateway Thread=qtp14486859-12 MDC=16d7cc4c-c9da-449b-8bfa-504e6d81185d failure occurred in gateway sendAndReceive: error occurred in message handler [webserviceOutboundGateway]; nested exception is org.springframework.ws.client.WebServiceTransportException: Not Found [404]
2020-05-20 22:21:48,162 DEBUG org.springframework.integration.gateway.GatewayProxyFactoryBean$MethodInvocationGateway Thread=qtp14486859-12 MDC=16d7cc4c-c9da-449b-8bfa-504e6d81185d failure occurred in gateway sendAndReceive: error occurred in message handler [webserviceOutboundGateway]; nested exception is org.springframework.ws.client.WebServiceTransportException: Not Found [404]
2020-05-20 22:21:48,167 ERROR com.acme.webservice.OrchestrationServiceEndpoint Thread=qtp14486859-12 MDC=16d7cc4c-c9da-449b-8bfa-504e6d81185d Error
org.springframework.ws.client.WebServiceTransportException: Not Found [404]
        at org.springframework.ws.client.core.WebServiceTemplate.handleError(WebServiceTemplate.java:699)
        at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:609)
        at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
        at org.springframework.integration.ws.MarshallingWebServiceOutboundGateway.doHandle(MarshallingWebServiceOutboundGateway.java:87)
        at com.acme.webservice.MarshallingWebServiceOutboundGateway.doHandle(MarshallingWebServiceOutboundGateway.java:60)
        at org.springframework.integration.ws.AbstractWebServiceOutboundGateway.handleRequestMessage(AbstractWebServiceOutboundGateway.java:188)
        at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109)
        at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
        at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
        at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148)
        at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
        at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:425)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:375)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:183)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:162)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
        at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:108)
        at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:194)
        at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
        at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
        at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148)
        at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
        at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:425)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:375)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:183)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:162)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
        at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:108)
        at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:360)
        at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:271)
        at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:188)
        at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115)
        at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
        at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
        at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148)
        at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
        at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:425)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:375)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:183)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:162)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)

我将trapExecution设置为false,直接将通知添加到网关,并且必须使用SetonFailureExpressionString,否则流将挂起。所以现在看起来是这样的:

@Bean
@Autowired
public MarshallingWebServiceOutboundGateway webserviceOutboundGateway(...) {
    MarshallingWebServiceOutboundGateway gateway = new ...;
    gateway.setAdviceChain(Arrays.asList(skipAdvice()));
    return gateway;
}

@Autowired
@Qualifier("skipCallChannel")
private MessageChannel skipCallChannel;

@Bean
public Advice skipAdvice() {
    ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
    advice.setFailureChannel(endChannel);
    advice.setOnFailureExpressionString("payload + ' was bad, with reason: ' + #exception");
    advice.setTrapException(true);
    return advice;
}

我得到以下错误:

2020-05-21 14:45:13,921 DEBUG org.springframework.integration.handler.BridgeHandler Thread=qtp14486859-19 MDC=16d7cc4c-c9da-449b-8bfa-504e6d81185d org.springframework.integration.handler.BridgeHandler@cdf55 received message: ErrorMessage [payload=org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice$MessageHandlingExpressionEvaluatingAdviceException: Handler Failed; nested exception is org.springframework.ws.client.WebServiceTransportException: Not Found [404], failedMessage=GenericMessage [payload=uk.co.acme._2009._03.ProcessTran@1759824, headers={replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@1ddbf77, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@1ddbf77, header.cqs.model=com.acme.model.FlowModel@cc006f, ws_soapAction=http://www.acme.co.uk/XRTEService/2009/03/ProcessTran, id=59e305ee-1672-d5ba-db4b-672198f25ab8, timestamp=1590068713891}], headers={id=14aeb6ed-77af-52bf-6b53-72bc0a4bb5c1, timestamp=1590068713921}]
2020-05-21 14:45:13,922 DEBUG org.springframework.integration.transformer.ContentEnricher$Gateway Thread=qtp14486859-19 MDC=16d7cc4c-c9da-449b-8bfa-504e6d81185d failure occurred in gateway sendAndReceive: Dispatcher failed to deliver Message; nested exception is org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available
2020-05-21 14:45:13,922 DEBUG org.springframework.integration.gateway.GatewayProxyFactoryBean$MethodInvocationGateway Thread=qtp14486859-19 MDC=16d7cc4c-c9da-449b-8bfa-504e6d81185d failure occurred in gateway sendAndReceive: Dispatcher failed to deliver Message; nested exception is org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available
2020-05-21 14:45:13,927 ERROR com.acme.webservice.OrchestrationServiceEndpoint Thread=qtp14486859-19 MDC=16d7cc4c-c9da-449b-8bfa-504e6d81185d Error
org.springframework.messaging.MessagingException: Dispatcher failed to deliver Message; nested exception is org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available
        at org.springframework.integration.dispatcher.AbstractDispatcher.wrapExceptionIfNecessary(AbstractDispatcher.java:133)
        at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:120)
        at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148)
        at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
        at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:425)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:375)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:183)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:162)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
        at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:108)
        at org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice.evaluateFailureExpression(ExpressionEvaluatingRequestHandlerAdvice.java:271)
        at org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice.doInvoke(ExpressionEvaluatingRequestHandlerAdvice.java:221)
        at org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice.invoke(AbstractRequestHandlerAdvice.java:70)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
        at com.sun.proxy.$Proxy190.handleRequestMessage(Unknown Source)
        at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.doInvokeAdvisedRequestHandler(AbstractReplyProducingMessageHandler.java:127)
        at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:112)
        at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
        at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
        at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148)
        at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
        at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:425)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:375)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:183)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:162)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
        at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:108)
        at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:194)
        at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
        at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
        at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148)
        at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
        at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:425)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:375)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:183)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:162)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
        at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:108)

我认为必须添加通道才能成功执行,但我不想这样做,因为它已经在处理程序所在的流中定义了(请参见.channel(OUTPUT_CHANNEL))。我可以在建议中只设置故障通道吗?
谢谢!

2020-05-22 10:10:48,023 ERROR com.acme.webservice.OrchestrationServiceEndpoint Thread=qtp14486859-13 MDC=16d7cc4c-c9da-449b-8bfa-504e6d81185d Error
org.springframework.messaging.MessagingException: failure occurred in error-handling flow; nested exception is org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'enrich.acmeRequest.output'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers, failedMessage=GenericMessage [payload=uk.co.acme.payload.request._2017._06.Message@4a5e6c, headers={replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@19d4520, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@19d4520, ws_soapAction=http://www.acme.co.uk/XRTEService/ProcessTran, id=902bd270-89d8-62e9-b00f-b69399241bd1, timestamp=1590138648017}], ...}]
    at org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:489)
    at org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceiveMessage(MessagingGatewaySupport.java:426)
    at org.springframework.integration.transformer.ContentEnricher$Gateway.sendAndReceiveMessage(ContentEnricher.java:481)
    at org.springframework.integration.transformer.ContentEnricher.handleRequestMessage(ContentEnricher.java:383)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
    return flow -> flow.channel(ORCH_REQUEST_INPUT)
            .<HomeRequest, HomeModel>transform(requestToModelTransformer)
            ...
            // 
            .enrich(this::acmePreCompRequestEnricher)
            .enrich(this::acmePreCompEnricher)
            .handle(this.acmePreCompResponseValidator())
            // 
            .enrich(this::mlRequestEnricher)
            .enrich(this::mlEnricher)
            // 
            .enrich(this::acmeRequestEnricher)
            .enrich(this::acmeEnricher)
            ...
    return flow -> flow.channel("skip.ml.input")
            .transform(ErrorMessage.class, (ErrorMessage m) -> {
                        Message originalMessage = ((MessageHandlingException)m.getPayload()).getFailedMessage();
                        return MessageBuilder.withPayload(originalMessage.getHeaders().get(HEADER_CQS_MODEL, HomeQuoteModel.class))
                                .copyHeaders(originalMessage.getHeaders())
                                .build();
                    })
            .channel("enrich.acmeRequest.output");

enrice.acmerequest.output通道是acmerequestenricher的应答通道。我的意图是,如果没有错误,那么执行流中的所有任务,但是如果acmeprecompenricher中有SOAP错误,那么跳过mlrequestenrichermlenricher直接转到acmerequestenricher
我认为问题是在faul场景中,SI看不到订阅了acmerequestenricher...?在这种情况下我能做什么?

共有1个答案

苏涵润
2023-03-14

请参阅ExpressionEvaluatingRequestHandlerAdvision上的此方法:

/**
 * If true, any exception will be caught and null returned.
 * Default false.
 * @param trapException true to trap Exceptions.
 */
public void setTrapException(boolean trapException) {

因此,将其设置为true以避免异常重新引发。

请参阅文档:https://Docs.spring.io/spring-integration/Docs/5.3.0.release/reference/html/messaging-endpoints.html#expression-advision

/**
 * Configure a list of {@link Advice}s to proxy a {@link #handleRequestMessage(Message)} method.
 * @param adviceChain the list of {@link Advice}s to use.
 */
public void setAdviceChain(List<Advice> adviceChain) {
 类似资料:
  • 我正在尝试将spring集成配置为向队列发送消息,然后接收消息,即非常简单的事情: 我认为解耦所必需的是在流程的两端都有一个消息网关。因此,我的第一次尝试(有效)如下所示: 其中MessageReceiverHandler()是扩展AbstractMessageHandler的bean。 所以上面我们有一个用于出站消息的消息网关。我假设我们也应该有一个用于入站消息的网关,允许我们将传入消息处理与应

  • 我能够使用Publish/SubscribeRabbitMQ Java教程创建扇出交换,任何连接的使用者都将收到一个消息的副本。我想在连接任何使用者之前创建交换和绑定,而不是动态/编程地声明交换和绑定。我已经通过RabbitMQ管理控制台完成了这一点。然而,由于某种原因,我的消费者以循环方式接收消息,而不是全部接收消息的副本。我错过了什么?下面是一些代码片段: 发布者: 消费者: ...在Rabb

  • 问题内容: 我正在按照本教程进行操作,试图在我的MVC3应用程序中包含一个SPA,该SPA由控制器DemoController.cs调用。 当应用尝试通过导航栏加载不同的模板(about.html,contact.html和home.html)时,出现404错误。 这是我的目录结构(不包括MVC3应用程序的其余部分): 这是我的script.js文件,我在其中定义路由。 这是我的index.htm

  • 我用java从MySQL查询了一些记录。但是在一些查询中,我遇到了一个问题,使查询失败,但在其他情况下,它查询成功。错误消息是下一个: 我尝试过一些方法,比如: 在 但什么都没发生。 我的环境是: MySQL: 5.5.3-m3-log源代码分布 Java: 1.60_16 jdk: HotSpot(TM)64位服务器VM(构建14.2-b01,混合模式) JDBC: mysql连接器-java-

  • 根据问题我得到输入为"/分裂/名称?FullName=ritik verma",我必须把它分成名字和姓氏,第二部分是"/计算/年龄?dob=17-04-1999"和我需要计算年龄。 所以我给你一个实际的问题也许这会有帮助 问题是:- 创建具有以下路由并在端口3000上运行的Express应用程序- 路由1-GET /split/name-它将fullName作为查询参数,并将firstName和l

  • 下一个是我。js教程https://github.com/zeit/next-learn-demo.git在超过第2阶段“动态路由”的所有阶段都存在问题。即使在阶段3至8之后的阶段中,动态路由应该已经在工作。 我认为问题是文件.next/routing似乎丢失了。 因此,本教程要求代码的实现: 和 不做任何事情。 导致单击链接时出现错误: 下一步.js浏览器语法错误检查的屏幕截图 为什么路由文件不