You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by "Walke, Martin (Leonardo, UK)" <ma...@leonardocompany.com> on 2019/01/24 09:42:28 UTC

Detecting netty4 client disconnect [General Use]

Hi,

Camel is fairly new to me so I'd like some help in my ignorance :-)

I see there's a number of posts about this but either the netty4 component is acting as a server, or the question hasn't been answered. In our case, we're using Camel as a client.

We have created our own component that's used in a DSL defined route. It utilises netty tcp as the consumer and a JMS queue as the producer and is deployed in JBoss-EAP 7. Everything works as we want and has been successful. The component is created by using decoders (and encoders) - not pipelines.

    public CdceComponent() {
        super();

        List<ChannelHandler> decoders = new ArrayList<ChannelHandler>();
        List<ChannelHandler> encoders = new ArrayList<ChannelHandler>();

        decoders.add(new DelimitedFieldBasedFrameDecoderFactory());
        decoders.add(new ByteArrayDecoderFactory());
        
        encoders.add(ChannelHandlerFactories.newByteArrayEncoder("tcp"));

        NettyConfiguration configuration = new NettyConfiguration();
        configuration.setSync(false); // one way MEP
        configuration.setTcpNoDelay(true);
        configuration.setKeepAlive(true);
        configuration.setDecoders(decoders);
        configuration.setEncoders(encoders);
        configuration.setClientMode(true); // The component is a TCP and will connect to Server Socket

        // Reconnect to the socket server if disconnected
        final int reconnectIntervalMilliSecs = 100;
        configuration.setReconnect(true);
        configuration.setReconnectInterval(reconnectIntervalMilliSecs);

        setConfiguration(configuration);
    }

The decoder classes are pretty basic, e.g.

public class ByteArrayDecoderFactory implements ChannelHandlerFactory {

    private static final String ROUTE_LOGGER = "routeLogger";
    private static final Logger logger = LogManager.getLogger(ROUTE_LOGGER);

    @Override
    public final ChannelHandler newChannelHandler() {
        return new ByteArrayDecoder();
    }

    @Override
    public void handlerAdded(final ChannelHandlerContext ctx) throws Exception { }

    @Override
    public void handlerRemoved(final ChannelHandlerContext ctx) throws Exception { }

    @Override
    public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) throws Exception {
        logger.info(cause.getLocalizedMessage());
    }

Similarly, the route is simple:

    private static final String ROUTE1NAME = "cdce1";

    /**
     * Configure the camel route with Java DSL.
     */
    @Override
    public final void configure() {

        String cdce_input = "cdce:tcp://localhost:12021";        
        String autotCdceTOOutput = "jms:topic:tOReqMessageTopic";
        String autotCdceOutput = "jms:topic:cdceMessageTopic";
        
        onException(Exception.class)
            .to("log:com.xxxxxxxx.camel_autoT?showCaughtException=true&level=ERROR&multiline=true")
            .handled(true)
            .end();
            
        // CDCE Message is input to the route via the CDCE service
        from(cdce_input).routeId(ROUTE1NAME)
            .log(LoggingLevel.DEBUG, ROUTE_LOGGER, "About to process ${routeId}: ${body}")
            .process(new MessageProcessor())
            .log(LoggingLevel.DEBUG, ROUTE_LOGGER, "Processed ${routeId}: ${body}")
            .choice()
                .when(header("type").isEqualTo(TestFlag.NORMAL))      
                    .log(LoggingLevel.DEBUG, ROUTE_LOGGER, "${routeId}: Detected NORMAL message\"")
                    .to(autotCdceOutput).endChoice()
                .otherwise()
                    .log(LoggingLevel.DEBUG, ROUTE_LOGGER, "${routeId}: Detected TEST message\"")
                    .to(autotCdceTOOutput).endChoice();
    }

The one issue we have is that the netty4 component is acting as a client which is sent messages from an external source. This source randomly disconnects and we wish to:
   - Detect when this disconnect happens;
   - Reinitialise the component to reconnect to the server.

We never see any log message from the 'exceptionCaught' method, when the server disconnects.    

The only other solution we have is to restart JBoss - which is installed as a service. This is not really acceptable as it's installed as a component in a critical system.

Can anyone suggest how this may be done? I guess I may have to write my own handler which seems odd as Camel attempts to remove the user from the lower levels of the protocols.

TIA
Martin
Leonardo MW Ltd
Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 3EL
A company registered in England & Wales.  Company no. 02426132
********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************