2

I am trying to communicate to a legacy (non spring) system via TCP using TcpOutboundGateway and process the response but I get the following error: DestinationResolutionException: no output-channel or replyChannel header available

The code kicks of example legacy listener, and then the launches spring boot application.

I am struggling to figure out what I am doing wrong - or if I am am even taking the right approach. Any suggestions would be appreciated.

(I had format problems posting here with some annotations, so removes @) TY

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Test {

    private static MessageChannel sendChannel;

    @Bean
    public MessageChannel replyChannel() {
        return new DirectChannel();
    }

    @Bean
    public MessageChannel sendChannel() {
        MessageChannel directChannel = new DirectChannel();
        sendChannel = directChannel;
        return directChannel;
    }

    @Bean
    TcpNetClientConnectionFactory tcpNetClientConnectionFactory() {
        TcpNetClientConnectionFactory tcpNetClientConnectionFactory = new TcpNetClientConnectionFactory("me.me", 9003);
        return tcpNetClientConnectionFactory;
    }

    @Bean
    @ServiceActivator(inputChannel = "sendChannel", outputChannel = "replyChannel", requiresReply = "true")
    TcpOutboundGateway tcpOutboundGateway() {
        TcpOutboundGateway tcpOutboundGateway = new TcpOutboundGateway();
        tcpOutboundGateway.setConnectionFactory(tcpNetClientConnectionFactory());
        tcpOutboundGateway.start();
        return tcpOutboundGateway;
    }


    public static void main(String args[]) {
        new LegacyApplication();

        SpringApplication.run(Test.class, args);
        Test.sendChannel.send(new GenericMessage("mgr?task=-1"));
    }
}

@MessageEndpoint
class ReplyListener {

    @ServiceActivator(inputChannel = "replyChannel")
    public void telemetryHandler(String message) {
        System.out.println(message);
    }

}

class LegacyApplication implements Runnable {

    public LegacyApplication() {
        (new Thread(this)).start();
    }

    @Override
    public void run() {
        try {
            ServerSocket serverSocket = new ServerSocket(9003);
            Socket clientSocket = serverSocket.accept();
            System.out.println("LegacyApplication: Accepted");
            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

            System.out.println("LegacyApplication: " + in.readLine());
            out.write("OK\r\n");
            out.flush();

            System.out.println("LegacyApplication: Done");
            clientSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Artem Bilan
  • 113,505
  • 11
  • 91
  • 118

1 Answers1

2

See the note in the documentation. When annotating a @Bean with @ServiceActivator, the output channel needs to go on the message handler (gateway bean), not the annotation.

You also should not call start(). Let the context do that.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • ` @Bean @ServiceActivator(inputChannel = "sendChannel") TcpOutboundGateway tcpOutboundGateway() { TcpOutboundGateway tcpOutboundGateway = new TcpOutboundGateway(); tcpOutboundGateway.setConnectionFactory(tcpNetClientConnectionFactory()); tcpOutboundGateway.setReplyChannel(replyChannel()); tcpOutboundGateway.setRequiresReply(true); return tcpOutboundGateway; } ` – Russell Maytham Apr 20 '15 at 20:57