Search code examples
springapache-camelnettyfuseesbjbossfuse

LengthFieldBasedFrameDecoder not working


I am having following code in Spring DSL

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:camel="http://camel.apache.org/schema/spring"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="
         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
         http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd 
         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        "
    >

    <util:list id="decoders" list-class="java.util.LinkedList">
        <bean id="length-decoder" class="org.apache.camel.component.netty.ChannelHandlerFactories" factory-method="newLengthFieldBasedFrameDecoder">
            <constructor-arg value="5000"/>
            <constructor-arg value="0"/>
            <constructor-arg value="4"/>
            <constructor-arg value="0"/>
            <constructor-arg value="4"/>
        </bean>
        <bean id="string-decoder" class="org.jboss.netty.handler.codec.string.StringDecoder"/>
    </util:list>

    <bean id="length-decoder" class="org.apache.camel.component.netty.ChannelHandlerFactories" factory-method="newLengthFieldBasedFrameDecoder">
        <constructor-arg value="5000"/>
        <constructor-arg value="0"/>
        <constructor-arg value="4"/>
        <constructor-arg value="0"/>
        <constructor-arg value="4"/>
    </bean>

    <bean id="string-decoder" class="org.jboss.netty.handler.codec.string.StringDecoder"/>

    <camelContext xmlns="http://camel.apache.org/schema/spring">
        <route>
            <from uri="netty:tcp://10.1.33.204:9001?keepAlive=true&decoders=#length-decoder,#string-decoder&disconnect=true" />
            <log message="${body}" loggingLevel="INFO"/>
            <to uri="direct:SMSRequests"/>
        </route>

        <route>
           <from uri="direct:SMSRequests"/>
           <log message="${body}" loggingLevel="INFO"/>
           <setBody><simple>0004THIS</simple></setBody> <!--hardcoded response-->
           <log message="response --- ${body}" loggingLevel="INFO"/>
         </route>
    </camelContext>

</beans>

My input is like 1200<XML>....</XML> where 1200 is the length of the message starting with <XML>.

My issues are:

  1. I see that the requests are coming to port 9001 and are reaching to Netty but Netty is not able to decode them.
  2. Netty is not decoding messages (Do I need to add encoders as well?)
  3. Also, do I need to add decoders to registry? I guess beans are automatically looked up in registry in Spring dsl.
  4. Also no response is sent to caller.

Solution

    • You don't need to define decoders if you don't reference the set in the uri
    • You don't need any encoders if you are not sending data to a Netty server and if you are only receiving data from a Netty server
    • You need to add length-decoder and/or string-decoder to the registry or you cannot reference them in the uri
    • Perhaps you may set lengthFieldOffset (the first constructor parameter of the lenght-decoder) to 0 if there is no offset