首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果DSL中的出站网关引发故障,则路由到错误通道

如果DSL中的出站网关引发故障,则路由到错误通道
EN

Stack Overflow用户
提问于 2020-05-20 20:53:12
回答 2查看 697关注 0票数 1

我有以下DSL代码:

代码语言:javascript
复制
    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故障到达时,将错误消息路由到错误通道。我认为我可以向处理程序添加一个建议,这个建议应该是一个ExpressionEvaluatingRequestHandlerAdvice,在这里我可以设置失败通道。因此,每当在出站网关中抛出错误时,错误消息将被转发到错误通道。

然后问题是,现在网关抛出一个异常,流停止。

代码语言:javascript
复制
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)

任何建议/帮助都将不胜感激!

谢谢,

V。

UPDATE1

我将trapExecution设置为false,将通知直接添加到网关,我不得不使用setOnFailureExpressionString,否则流就挂起了。现在的情况如下:

代码语言:javascript
复制
@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;
}

我得到了以下错误:

代码语言:javascript
复制
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))。我可以在建议中只设置故障通道吗?

谢谢!

UPDATE2

我按照Gary的建议(即向上游流添加了一个错误通道),现在将错误消息传递到错误通道。然而,我现在有另一个问题,它与我原来的问题有着模糊的关系。因此,现在我有以下例外:

代码语言:javascript
复制
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)

在主要流程中,我有以下几点:

代码语言:javascript
复制
    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)
            ...

在使用出站网关的acmePreCompEnricher中引发SOAP故障。错误通道被设置为skip.ml.input,然后我必须遵循处理错误的流程:

代码语言:javascript
复制
    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");

enrich.acmeRequest.output通道是acmeRequestEnricher的应答通道。我的意图是,如果没有错误,那么执行流中的所有任务,但是如果acmePreCompEnricher中有SOAP错误,那么跳过mlRequestEnrichermlEnricher,直接转到acmeRequestEnricher

我想问题是,在faul场景中,SI看不到订阅acmeRequestEnricher.通道的内容?在这种情况下我能做什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-22 13:22:38

正如Gary在他的评论中所建议的那样,我在上游流中设置了一个错误通道(参见UPDATE2)。

票数 0
EN

Stack Overflow用户

发布于 2020-05-20 21:06:06

ExpressionEvaluatingRequestHandlerAdvice上看到此方法

代码语言:javascript
复制
/**
 * If true, any exception will be caught and null returned.
 * Default false.
 * @param trapException true to trap Exceptions.
 */
public void setTrapException(boolean trapException) {

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

在Docs中也可以看到更多信息:https://docs.spring.io/spring-integration/docs/5.3.0.RELEASE/reference/html/messaging-endpoints.html#expression-advice

UPPDATE

因为除了建议之外,一切都能工作,所以它看起来就像过时的Java项目中的一个bug。请考虑将您的skipAdvice直接注入webserviceOutboundGateway。它有一个各自的策划人:

代码语言:javascript
复制
/**
 * 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) {

UPDATE2

好的。看起来,在处理SOAP错误之后,您需要发送一个回复。所以,您可能不需要那种failureChannel配置。到目前为止,表达式应该足够捕获一个异常,并将一些简单的字符串发送回顶部的网关作为答复。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61922689

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档