Estoy escribiendo una aplicación Spring Integration que usa el patrón Scatter-Gather. El código de mi servidor usa Pippo para atender solicitudes como esta:

public static void main(String[] args) {
    Pippo pippo = new Pippo();
    pippo.GET("/one", routeContext -> {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        routeContext.send("One Hello World!");
    });
    pippo.GET("/two", routeContext -> routeContext.send("Two Hello World!"));
    pippo.GET("/three", routeContext -> {
        throw new RuntimeException("err");
    });
    pippo.start();
}

En la tercera solicitud, el servidor falla. Mi configuración de primavera es esta:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-http="http://www.springframework.org/schema/integration/http"
xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/integration
    http://www.springframework.org/schema/integration/spring-integration.xsd
    http://www.springframework.org/schema/integration/http
    http://www.springframework.org/schema/integration/http/spring-integration-http.xsd">

<int:gateway service-interface="ro.oss.thirdparty.PippoGateway" />

<int:channel id="inputDistribution" />
<int:channel id="gatherChannel" />
<int:channel id="distribution1Channel" />
<int:channel id="distribution2Channel" />
<int:channel id="distribution3Channel" />

<int:scatter-gather input-channel="inputDistribution"
    gather-channel="gatherChannel">
    <int:scatterer apply-sequence="true">
        <int:recipient channel="distribution1Channel" />
        <int:recipient channel="distribution2Channel" />
        <int:recipient channel="distribution3Channel" />
    </int:scatterer>
</int:scatter-gather>

<int-http:outbound-gateway request-channel="distribution1Channel"
    url="http://localhost:8338/one" http-method="GET" expected-response-type="java.lang.String" />
<int-http:outbound-gateway request-channel="distribution2Channel"
    url="http://localhost:8338/two" http-method="GET" expected-response-type="java.lang.String" />
<int-http:outbound-gateway request-channel="distribution3Channel"
    url="http://localhost:8338/three" http-method="GET" expected-response-type="java.lang.String" />

¿Hay alguna manera de ignorar el canal que me dio el error y simplemente cobrar de los buenos? Ahora obtengo algo como esto en la consola:

Exception in thread "main" org.springframework.web.client.HttpServerErrorException: 500 Server Error
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:94)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:628)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:549)
at org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler.handleRequestMessage(HttpRequestExecutingMessageHandler.java:382)
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:423)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:373)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:194)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
at org.springframework.integration.channel.FixedSubscriberChannel.send(FixedSubscriberChannel.java:70)
at org.springframework.integration.channel.FixedSubscriberChannel.send(FixedSubscriberChannel.java:64)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.

Gracias

2
Daniel Jipa 15 ene. 2017 a las 15:17

1 respuesta

La mejor respuesta

El agregador (recolector) necesita 3 respuestas.

Puede agregar un ExpressionEvaluatingRequestHandlerAdvice a cada puerta de enlace, con un failureExpression y establecer returnFailureExpressionResult en verdadero; cuando ocurre una excepción, la expresión se evalúa y su resultado se devolverá para ser agregado con los otros resultados.

Consulte Adición de comportamiento a Extremos.

1
Gary Russell 15 ene. 2017 a las 18:01
Gracias, eso funcionó. Quería preguntar algo nuevo, no sé si debería plantear una nueva pregunta. Si quiero filtrar algunos mensajes en uno de los canales distribuidos, bloquea todo porque no tengo respuesta de uno de los canales. ¿También es esta una configuración? Gracias
 – 
Daniel Jipa
16 ene. 2017 a las 15:55
Por lo general, debe hacer una nueva pregunta (haciendo referencia a esta si es necesario); a los administradores aquí no les gustan los comentarios extendidos. Puede personalizar el recolector con una estrategia de lanzamiento personalizada docs here y aquí. Sin embargo, su estrategia de lanzamiento necesitará algún mecanismo para saber cuándo se completa el grupo. Probablemente sea más fácil enrutar a una respuesta diferente en lugar de filtrar.
 – 
Gary Russell
16 ene. 2017 a las 17:06