0

I'm working with Spring Integration and trying to handle TcpConnectionOpenEvent and TcpConnectionCloseEvent to collect metrics on the connections and to write to the log. However, I'm not able to listen to these events properly. This is working without interceptors But when I'm adding the interceptor-factory-chain as below the events listener is not works.

Could you provide guidance on how to properly set up event listeners for these connection events?

Here are the relevant configurations I have:

<int-ip:tcp-connection-factory id="crLfServer"
                                   using-nio="false"
                                   deserializer="serverDeserializer"
                                   serializer="serverSerializer"
                                   single-use="false"
                                   lookup-host="false"
                                   type="server"
                                   **interceptor-factory-chain="serverConnectionInterceptorFactoryChain"**
                                   task-executor="incomingTaskExecutor"
                                   ssl-context-support="${sslcontext.server.beanname}"
                                   socket-support="requireClientAuthSocketSupport"
                                   port="${local.server.port}"/>

<int-ip:tcp-inbound-gateway id="gatewayCrLf"
                                reply-timeout="${pos.server.timeout}"
                                connection-factory="crLfServer"
                                request-channel="serverInChannelPos"
                                reply-channel="serverOutChannelPos"
                                error-channel="errorChannel" />


 <int:channel id="serverOutChannelPos">
        <int:interceptors>
            <ref bean="serverOutInterceptor"/>
            <ref bean="errorMessageChannelInterceptor"/>
        </int:interceptors>
    </int:channel>


    <int:channel id="serverInChannelPos">
        <int:interceptors>
            <ref bean="serverInInterceptor"/>
        </int:interceptors>
    </int:channel>

I've also added an event listener class:

@Component
@Slf4j
public class TcpConnectionEventListener {

    @EventListener
    public void handleTcpConnectionOpen(TcpConnectionOpenEvent event) {
        log.info("TCP connection opened: {}", event.getConnectionId());
        //collect metrics
        //some other actions...
    }

    @EventListener
    public void handleTcpConnectionClose(TcpConnectionCloseEvent event) {
        log.info("TCP connection closed: {}", event.getConnectionId());
        //collect metrics
        //some other actions...
    }
}
  @Bean
    @Lazy
    public TcpConnectionInterceptorFactoryChain serverConnectionInterceptorFactoryChain(){
        TcpConnectionInterceptorFactoryChain tcpConnectionInterceptorFactoryChain = new TcpConnectionInterceptorFactoryChain();
        TcpConnectionInterceptorFactory[] tcpConnectionInterceptorFactories = {
                serverRetailerNumberValidationInterceptorFactory(),
                serverStoringConnectionIdInterceptorFactory()};
        tcpConnectionInterceptorFactoryChain.setInterceptors(tcpConnectionInterceptorFactories);
        return tcpConnectionInterceptorFactoryChain;
    }

The issue is that I don't see any logs from the @EventListener methods, and it seems they are not triggered at all. Could you help me identify what might be wrong and how to get these events to work properly along with interceptors?

4
  • Please, make sure that your TcpConnectionEventListener makes it into a bean for application context. Plus those events happen only if client is connected/disconnected to/from your server. Otherwise we will be more than happy to help you if you share some simple project to reproduce on our side. Commented Sep 10, 2024 at 13:42
  • @ArtemBilan we noticed that when we remove the interceptors configuration from the TCP connection factory, the event listener works as expected. I have edited the question above. Could you please respond? Commented Sep 11, 2024 at 12:16
  • We don't know what are yours serverRetailerNumberValidationInterceptorFactory() and serverStoringConnectionIdInterceptorFactory(), but they have to be supplied with an ApplicationEventPublisher according to the TcpConnectionInterceptorSupport and TcpConnectionInterceptorFactory contract. Commented Sep 11, 2024 at 13:30
  • @ArtemBilan We added to the existing ServerStoringConnectionIdInterceptorFactory implement of ApplicationEventPublisherAware and implemented setApplicationEventPublisher in addition, we injected the applicationEventPublisher here: Override public TcpConnectionInterceptorSupport getInterceptor() { return new TcpConnectionInterceptorSupport(applicationEventPublisher) { .... //other override methods } Thanks a lot for your explanation and example, we were able to get events! Commented Sep 12, 2024 at 8:16

1 Answer 1

0

So, after some local testing here is a conclusion.

When you use TcpConnectionInterceptorFactoryChain, you have to ensure that TcpConnectionInterceptorFactory produces TcpConnectionInterceptorSupport supplied with an ApplicationEventPublisher. For example like this:

public class HelloWorldInterceptorFactory implements
        TcpConnectionInterceptorFactory, ApplicationEventPublisherAware {

        
    private volatile ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    @Override
    public TcpConnectionInterceptorSupport getInterceptor() {
        return new HelloWorldInterceptor(this.hello, this.world, this.applicationEventPublisher);
    }

}

The ConnectionFactory is supplied with one automatically, but it is not its responsibility to mutate interceptor instances supplied by the mentioned factory. Therefore it is target project responsibility to wire interceptors properly if we'd like to emit the mentioned events.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.