1
votes

I'm receiving an error in my application that I am not getting a solution. The application requests a REST/JSON and tries to comunicate with another aplication. There is a poller that invoke each request asynchronously. When a do a request always dispatcher the error "no output-channel or replyChannel header available" and it is redirect to errorChannel handles.

...
@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();
}

the log prints:

postSend (sent=true) on channel 'errorChannel', message: ErrorMessage [payload=org.springframework.messaging.MessagingException: Dispatcher failed to deliver Message; nested exception is org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available, headers={id=826074c0-d1c6-4ecf-44f0-6da697b29f9c, timestamp=1484650523378}]

Update after Gary Russel sugestion

...

@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();
}

The log

2017-01-17 13:58:31.929 DEBUG 19702 --- [ask-scheduler-9] o.s.integration.channel.DirectChannel : preSend on channel 'send.channel#3', message: GenericMessage [payload=$PAYLOAD_JSON, headers=$HEADERS] 2017-01-17 13:58:31.930 DEBUG 19702 --- [ask-scheduler-9] o.s.i.t.MessageTransformingHandler : org.springframework.integration.transformer.MessageTransformingHandler#0 received message: GenericMessage [payload=$PAYLOAD_JSON, headers=$HEADERS] 2017-01-17 13:58:31.932 DEBUG 19702 --- [ask-scheduler-9] o.s.integration.channel.DirectChannel : preSend on channel 'send.channel#5', message: GenericMessage [payload=$PAYLOAD_JSON, headers=$HEADERS] 2017-01-17 13:58:31.932 DEBUG 19702 --- [ask-scheduler-9] o.s.integration.handler.LoggingHandler : org.springframework.integration.handler.LoggingHandler#1 received message: GenericMessage GenericMessage [payload=$PAYLOAD_JSON, headers=$HEADERS] 2017-01-17 13:58:31.942 DEBUG 19702 --- [ask-scheduler-9] o.s.integration.handler.BridgeHandler : org.springframework.integration.handler.BridgeHandler#2 received message: GenericMessage [payload=$PAYLOAD_JSON, headers=$HEADERS] 2017-01-17 13:58:31.943 DEBUG 19702 --- [ask-scheduler-9] o.s.integration.channel.DirectChannel : preSend on channel 'nullChanel', message: GenericMessage [payload=$PAYLOAD_JSON, headers=$HEADERS] 2017-01-17 13:58:31.944 DEBUG 19702 --- [ask-scheduler-9] o.s.integration.channel.DirectChannel : preSend on channel 'errorChannel', message: ErrorMessage [payload=org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'application:29891.nullChanel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers, headers={id=fe0672cd-b9e4-9d43-2c5a-3d2d0a1c5493, timestamp=1484668711944}] 2017-01-17 13:58:31.945 DEBUG 19702 --- [ask-scheduler-9] o.s.integration.handler.LoggingHandler : org.springframework.integration.handler.LoggingHandler#2 received message: ErrorMessage [payload=org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'application:29891.nullChanel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers, headers={id=fe0672cd-b9e4-9d43-2c5a-3d2d0a1c5493, timestamp=1484668711944}] 2017-01-17 13:58:31.949 DEBUG 19702 --- [ask-scheduler-9] o.s.i.t.MessageTransformingHandler : org.springframework.integration.transformer.MessageTransformingHandler#1 received message: ErrorMessage [payload=org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'application:29891.nullChanel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers, headers={id=fe0672cd-b9e4-9d43-2c5a-3d2d0a1c5493, timestamp=1484668711944}] 2017-01-17 13:58:31.951 DEBUG 19702 --- [ask-scheduler-9] o.s.integration.channel.DirectChannel : preSend on channel 'errorFlow.channel#1', message: GenericMessage [payload=$PAYLOAD_JSON, headers=$HEADERS]

I replaced the payload and the header by $PAYLOAD_JSON and $HEADERS respectively to reduce the log.

1

1 Answers

1
votes

Your gateway has a void return void send(...) so the framework is not expecting a reply.

The .log() element is a wiretap (that's how the first log lets the message flow to the queue channel).

Since your flow ends with a log (wireTap) it is expecting a consumer of the message or a reply channel.

We could possibly make a final .log terminal and will look into that (INT-4210), but for now you can add .channel("nullChannel") after that final .log.