0

I'm using

  • spring-integration-java-dsl-1.2.3.RELEASE
  • spring-integration-ip-4.3.17.RELEASE
  • spring-integration-http-4.3.17.RELEASE

Given this code to generate dynamically TCP connections. I define a enricherHeader with a unique header called "connectionId". This "connectionId" will be the name of the connection created.

@Service
@EnableIntegration
public class TcpConnectionsHolder {

private static final Logger LOGGER = LoggerFactory.getLogger(TcpConnectionsHolder.class);

@Autowired
private IntegrationFlowContext flowContext;

//    @Autowired
//    private BridgeMessageEndpoint bme;

@Value("${socket.tcp.headBytes}")
private int headBytes;

@Value("${socket.tcp.retryInterval}")
private int retryInterval;

//@Qualifier("sendToApi")
@Autowired
private MessageChannel fromTcp;

private final static String CONNECTION_SUFFIX="_connection";    

public IntegrationFlow createTcpConnection(String connectionId, String host, int port, int headBytes,
        int retryInterval) 
{

    LOGGER.debug("createTcpConnection ->  connectionId: {} - host: {} - port: {} - headBytes: {} - retryInterval: {}"
            ,connectionId,host,port,headBytes,retryInterval);
    IntegrationFlow ifr = existsConnection(connectionId);
    if (ifr == null) {
        TcpNetClientConnectionFactory cf = new TcpNetClientConnectionFactory(host, port);
        final ByteArrayLengthHeaderSerializer by = new ByteArrayLengthHeaderSerializer(headBytes);
        cf.setSingleUse(false);
        cf.setSoKeepAlive(true);
        cf.setSerializer(by);
        cf.setDeserializer(by);
        cf.setComponentName(connectionId);

        //Inbound Adapter 
        TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
        adapter.setConnectionFactory(cf);
        adapter.setClientMode(true);
        adapter.setErrorChannelName("errorChannel");
        adapter.setRetryInterval(retryInterval);
        adapter.setOutputChannel(fromTcp);

        //OutBound Adapter
        TcpSendingMessageHandler sender = new TcpSendingMessageHandler();
        sender.setConnectionFactory(cf);

        ifr = IntegrationFlows
                .from(adapter)
                .enrichHeaders(h -> h.header("connec_id",connectionId))
                .handle(sender).get();

        this.flowContext.registration(ifr).id(connectionId+CONNECTION_SUFFIX).addBean(cf).register();
        LOGGER.debug("createTcpConnection: Connection created");
    }
    return ifr;
}

Also I have a MessageEndpoint class where I define all the serviceActivator methods

@Configuration
@MessageEndpoint
@EnableIntegration
public class BridgeMessageEndpoint{

private static final Logger LOGGER = LoggerFactory.getLogger(BridgeMessageEndpoint.class);

@Autowired
private ApplicationContext applicationContext;

@ServiceActivator(inputChannel = "fromTcp")
public void outbound(final String inMessage, final @Headers Map<String, Object> headerMap) {
    sendToApi(inMessage, headerMap);
}

private void sendToApi(final String inMessage, final Map<String, Object> headerMap) {
    LOGGER.debug("Recuperando el mensaje Hex {}", inMessage);
    final PaymentOrder paymentOrder = new PaymentOrder();
    paymentOrder.setMessage(inMessage);
    final SplitterRestClient splitterRestClient = applicationContext.getBean(SplitterRestClient.class);
    splitterRestClient.reportPayment(paymentOrder, headerMap);
}

@Bean
@ServiceActivator(inputChannel = "errorChannel")
public MessageHandler logger() {
    final LoggingHandler loggingHandler = new LoggingHandler(LoggingHandler.Level.DEBUG.name());
    loggingHandler.setLoggerName("Log");
    return loggingHandler;
}
/*
 * Calls TcpRouter to redirect the message to the correct TCP connection
 */
@Bean
public IntegrationFlow toTcp() {
    return f -> f.route(new TcpRouter());
}


@Bean
public MessageChannel fromTcp() {
    final DirectChannel channel = new DirectChannel();
    channel.addInterceptor(new ChannelInterceptorAdapter() {
        @Override
        public Message<?> preSend(final Message<?> message, final MessageChannel channel) {
            // Parse Message byte[] to StringHex
            final byte[] bMessagePayload = (byte[]) message.getPayload();
            return MessageBuilder.withPayload(Hex.encodeHexString(bMessagePayload))
                    .copyHeaders(message.getHeaders()).build();
        }
    });
    return channel;
}

Having said that. I have several issue what I need your help.

In the creationTcpconnection method I am trying to create dynamic connections, defining the receiver adapter and SenderAdapter.

If I comment out the line(adapter.setOutputChannel(fromTcp);) as I have recommended me, it doesn't work me the execution of serviceActivator (inputChannel="fromTcp") defined in BridgeMessageEndpoint class.

As I have commented you previously I need to send a new header called "connectionId" that identifies which connection has received the message from a tcp server for later to response to that same connection

Reyfren
  • 51
  • 1
  • 6
  • >`adapter.setOutputChannel(fromTcp());` That won't do anything when the adapter is used within an `IntegrationFlow`. The flow will replace that output channel with the header enricher's input channel. It's not at all clear what you are trying to do. Your flow simply wires an input adapter to an output adapter (with a header enricher that will really have no effect since the outbound adapter knows nothing about it. Perhaps edit your question to show the rest of the configuration and explain exactly what you are trying to accomplish. – Gary Russell Dec 27 '18 at 15:56
  • I'm trying to redirect the incoming message from the adapter to this channel that the service activator in the bean called outbound will capture and redirect to a restclient for further processing. My intention with header enrichment is to add a connection identification that i asign to the adapter for when the message has to be sent back to the server – Reyfren Dec 27 '18 at 19:09
  • But that's not what your flow `ifr` is doing; it's simply routing messages from the inbound adapter to the outbound adapter. You need something like `.from(adapter).enrichHeaders(...).handle(myService).get();`. Where `myService` is your service activator; since your service returns void, the flow ends at that point. If you want to send a reply, the service needs to return one, and then you can add `.handle(sender)`. If you want to add an interceptor, you need `.channel(fromTcp())` before the service. – Gary Russell Dec 27 '18 at 19:28

0 Answers0