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?
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.