Recibo un error en mi aplicación que indica que no obtengo una solución. La aplicación solicita un REST / JSON e intenta comunicarse con otra aplicación. Hay un sondeador que invoca cada solicitud de forma asincrónica. Cuando se hace una solicitud, siempre se envía el mensaje de error "no hay canal de salida o encabezado de responseChannel disponible" y se redirige a los identificadores de errorChannel.

...
@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata poller() {
    return Pollers              
            .fixedRate(NumberUtils.createLong(QUEUE_RATE))
            .get();
}

    @Bean
public MessageChannel errorChannel() {
    return MessageChannels.direct().get();
}

    @MessagingGateway 
public static interface HttpService {
    @Gateway(requestChannel = "service.input")
    void send(@Payload String body, @Headers MultiValueMap<String, String> headers);        
}


public MessageHandler httpOutboundAdapter(){
    HttpRequestExecutingMessageHandler handler = 
            Http.outboundGateway(URI, restTemplate)             
            .expectedResponseType(String.class)         
            .httpMethod(HttpMethod.POST)
            .mappedRequestHeaders("Authorization","Accept","Content-Type", "X-User-Email","X-User-Token")               
            .get();

    return handler;
}


@Bean
public FileWritingMessageHandler fileOutboundAdapter(){
    FileWritingMessageHandler fwmhs = Files
            .outboundAdapter(new File("logs/errors"))
            .autoCreateDirectory(true)
            .get();     

    return fwmhs;
}   

    @Bean
public IntegrationFlow send(){  
    return IntegrationFlows.from("service.input")
            .log(Level.DEBUG, "trace.http",
                    "'Request.\n'"+
                    ".concat('Headers : ').concat(headers.toString()).concat('\n')"+
                    ".concat('Payload : ').concat(payload.toString())"
                )                               
            .channel(MessageChannels.queue())
            .handle(this.httpOutboundAdapter()
            .transform(Transformers.toJson())
            .log(Level.DEBUG, "trace.http",
                    "'Response.\n'"+
                    ".concat('Headers : ').concat(headers.toString()).concat('\n')"+
                    ".concat('Payload : ').concat(payload.toString())"
                )
            .get();
}

    @Bean 
public IntegrationFlow errorFlow(){
    return IntegrationFlows.from(errorChannel())                                                                
                            .log(Level.DEBUG,"trace.http", "'Ocurred an error in httpResponse :'.concat(payload.message)")
                            .transform("payload.failedMessage")                             
                            .handle((p,h) -> 
                                        MessageBuilder.withPayload(new GenericMessage<>(p,h)))
                            .transform(Transformers.toJson())
                            .enrichHeaders(c -> c.headerExpression(FileHeaders.FILENAME, "'emailErrors-'.concat(headers.getTimestamp()).concat('.json')"))
                            .handle(fileOutboundAdapter())                              
                            .get();
}

El registro imprime:

postSend (enviado = verdadero) en el canal 'errorChannel', mensaje: ErrorMessage [payload = org.springframework.messaging.MessagingException: El despachador no pudo entregar el mensaje; La excepción anidada es org.springframework.messaging.core.DestinationResolutionException: no hay canal de salida o encabezado de replyChannel disponible, encabezados = {id = 826074c0-d1c6-4ecf-44f0-6da697b29f9c, timestamp = 1484650523378}]

Actualización después de la sugerencia de Gary Russel

...

@Bean
public IntegrationFlow send(){  
    return IntegrationFlows.from("service.input")
            .log(Level.DEBUG, "trace.http",
                    "'Request.\n'"+
                    ".concat('Headers : ').concat(headers.toString()).concat('\n')"+
                    ".concat('Payload : ').concat(payload.toString())"
                )                               
            .channel(MessageChannels.queue())
            .handle(this.httpOutboundAdapter()
            .transform(Transformers.toJson())
            .log(Level.DEBUG, "trace.http",
                    "'Response.\n'"+
                    ".concat('Headers : ').concat(headers.toString()).concat('\n')"+
                    ".concat('Payload : ').concat(payload.toString())"
                )
            .channel("nullChanel")
            .get();
}

El registro

2017-01-17 13: 58: 31.929 DEBUG 19702 --- [ask-Scheduler-9] osintegration.channel.DirectChannel: preSend en el canal 'send.channel # 3', mensaje: GenericMessage [payload = $ PAYLOAD_JSON, encabezados = $ HEADERS] 2017-01-17 13: 58: 31.930 DEBUG 19702 --- [ask-Scheduler-9] ositMessageTransformingHandler: org.springframework.integration.transformer.MessageTransformingHandler # 0 mensaje recibido: GenericMessage [payload = $ PAYLOAD_JSON, headers = $ HEADERS ] 2017-01-17 13: 58: 31.932 DEBUG 19702 --- [ask-Scheduler-9] osintegration.channel.DirectChannel: preSend en el canal 'send.channel # 5', mensaje: GenericMessage [payload = $ PAYLOAD_JSON, encabezados = $ HEADERS] 2017-01-17 13: 58: 31.932 DEBUG 19702 --- [ask-schedule-9] osintegration.handler.LoggingHandler: org.springframework.integration.handler.LoggingHandler # 1 mensaje recibido: GenericMessage GenericMessage [payload = $ PAYLOAD_JSON , encabezados = $ HEADERS] 2017-01-17 13: 58: 31.942 DEBUG 19702 --- [ask-schedule-9] osintegration.handler.BridgeHandler: org.springframework.integration.handler.BridgeHandler # 2 mensaje recibido: GenericMessage [payload = $ PAYLOAD_JSON, encabezados = $ HEADERS] 2017-01-17 13: 58: 31.943 DEBUG 19702 --- [ask-Scheduler-9] o.s.integration.channel.DirectChannel: preSend en el canal 'nullChanel', mensaje: GenericMessage [payload = $ PAYLOAD_JSON, headers = $ HEADERS] 2017-01-17 13: 58: 31.944 DEBUG 19702 --- [ask-Scheduler-9] osintegration.channel.DirectChannel: preSend en el canal 'errorChannel', mensaje: ErrorMessage [payload = org.springframework.messaging.MessageDeliveryException: Dispatcher no tiene suscriptores para el canal 'aplicación: 29891.nullChanel' .; La excepción anidada es org.springframework.integration.MessageDispatchingException: Dispatcher no tiene suscriptores, encabezados = {id = fe0672cd-b9e4-9d43-2c5a-3d2d0a1c5493, timestamp = 1484668711944}] 2017-01-17 13: 58: 31.945 DEBUG 19702 --- [ask-Scheduler-9] osintegration.handler.LoggingHandler: org.springframework.integration.handler.LoggingHandler # 2 mensaje recibido: ErrorMessage [payload = org.springframework .messaging.MessageDeliveryException: Dispatcher no tiene suscriptores para el canal 'aplicación: 29891.nullChanel' .; La excepción anidada es org.springframework.integration.MessageDispatchingException: Dispatcher no tiene suscriptores, encabezados = {id = fe0672cd-b9e4-9d43-2c5a-3d2d0a1c5493, timestamp = 1484668711944}] 2017-01-17 13: 58: 31.949 DEBUG 19702 --- [ask-Scheduler-9] ositMessageTransformingHandler: org.springframework.integration.transformer.MessageTransformingHandler # 1 mensaje recibido: ErrorMessage [payload = org.springframework.messaging.MessageDeliveryException : Dispatcher no tiene suscriptores para el canal 'aplicación: 29891.nullChanel' .; La excepción anidada es org.springframework.integration.MessageDispatchingException: Dispatcher no tiene suscriptores , headers = {id = fe0672cd-b9e4-9d43-2c5a-3d2d0a1c5493, timestamp = 1484668711944}] 2017-01-17 13: 58: 31.951 DEBUG 19702 --- [ask-Scheduler-9] osintegration.channel.DirectChannel: preSend en el canal 'errorFlow.channel # 1', mensaje: GenericMessage [payload = $ PAYLOAD_JSON, encabezados = $ HEADERS]

Reemplacé la carga útil y el encabezado por $ PAYLOAD_JSON y $ HEADERS respectivamente para reducir el registro.

1
Jan R. Krejci 17 ene. 2017 a las 13:56

1 respuesta

La mejor respuesta

Su puerta de enlace tiene un void retorno void send(...) por lo que el marco no espera una respuesta.

El elemento .log() es una escucha telefónica (así es como el primer registro permite que el mensaje fluya al canal de la cola).

Dado que su flujo termina con un registro (wireTap), se espera un consumidor del mensaje o un canal de respuesta.

Posiblemente podríamos hacer una terminal .log final y la analizaremos ( INT-4210 < / a>), pero por ahora puedes agregar .channel("nullChannel") después de ese .log final.

1
Gary Russell 17 ene. 2017 a las 21:17
Gracias por responder. Intenté como dijiste, pero lancé el mismo error pero ahora con el nombre "nullChannel".
preSend en el canal 'errorChannel', mensaje: ErrorMessage [payload = org.springframework.messaging.MessageDeliveryExceptionDispatcher no tiene suscriptores para el canal 'application: 29891.nullChanel' .; La excepción anidada es org.springframework.integration.MessageDispatchingException: Dispatcher no tiene suscriptores, headers = {id = 6f28519a-d7d3-4a84-2b76-960d340ec4c2, timestamp = 1484662227466}]
 – 
Jan R. Krejci
17 ene. 2017 a las 17:15
Yo mismo probé un flujo similar sin problemas: actualice la pregunta para mostrar su nueva configuración; también active el registro DEBUG para org.springframework.integration y muestre los últimos registros (en su pregunta, no en un comentario). También el seguimiento de la pila completa.
 – 
Gary Russell
17 ene. 2017 a las 17:18
>[payload=org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'application:29891.nullChanel' Eso no tiene ningún sentido, ¿anuló la definición predeterminada del bean nullChannel?
 – 
Gary Russell
17 ene. 2017 a las 20:07
Lo siento Gary. El canal se escribió incorrectamente. Lo cambié y trabajé de la manera que esperaba. Aceptaré tu respuesta. Muchas gracias por ayudarme. ¿Podría cambiar su respuesta a ".channel (" nullChannel ")"?
 – 
Jan R. Krejci
17 ene. 2017 a las 20:31