...
The URI scheme for a netty component is as follows
Code Block |
---|
nettynetty4:tcp://localhost:99999[?options] nettynetty4:udp://remotehost:99999/[?options] |
...
Div | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Registry based Options
Codec Handlers and SSL Keystores can be enlisted in the Registry, such as in the Spring XML file.
The values that could be passed in, are the following:
Div | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||
|
...
Code Block |
---|
KeyStoreParameters ksp = new KeyStoreParameters(); ksp.setResource("/users/home/server/keystore.jks"); ksp.setPassword("keystorePassword"); KeyManagersParameters kmp = new KeyManagersParameters(); kmp.setKeyStore(ksp); kmp.setKeyPassword("keyPassword"); SSLContextParameters scp = new SSLContextParameters(); scp.setKeyManagers(kmp); NettyComponent nettyComponent = getContext().getComponent("nettynetty4", NettyComponent.class); nettyComponent.setSslContextParameters(scp); |
...
The lists of codecs need to be added to the Camel's registry so they can be resolved when the endpoint is created.
Code Block |
---|
Wiki Markup |
{code} ChannelHandlerFactory lengthDecoder = ChannelHandlerFactories.newLengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4); StringDecoder stringDecoder = new StringDecoder(); registry.bind("length-decoder", lengthDecoder); registry.bind("string-decoder", stringDecoder); LengthFieldPrepender lengthEncoder = new LengthFieldPrepender(4); StringEncoder stringEncoder = new StringEncoder(); registry.bind("length-encoder", lengthEncoder); registry.bind("string-encoder", stringEncoder); List<ChannelHandler> decoders = new ArrayList<ChannelHandler>(); decoders.add(lengthDecoder); decoders.add(stringDecoder); List<ChannelHandler> encoders = new ArrayList<ChannelHandler>(); encoders.add(lengthEncoder); encoders.add(stringEncoder); registry.bind("encoders", encoders); registry.bind("decoders", decoders); {code} |
Spring's native collections support can be used to specify the codec lists in an application context
Code Block |
---|
Wiki Markup |
{code} <util:list id="decoders" list-class="java.util.LinkedList"> <bean class="org.apache.camel.component.netty4.ChannelHandlerFactories" factory-method="newLengthFieldBasedFrameDecoder"> <constructor-arg value="1048576"/> <constructor-arg value="0"/> <constructor-arg value="4"/> <constructor-arg value="0"/> <constructor-arg value="4"/> </bean> <bean class="io.netty.handler.codec.string.StringDecoder"/> </util:list> <util:list id="encoders" list-class="java.util.LinkedList"> <bean class="io.netty.handler.codec.LengthFieldPrepender"> <constructor-arg value="4"/> </bean> <bean class="io.netty.handler.codec.string.StringEncoder"/> </util:list> <bean id="length-encoder" class="io.netty.handler.codec.LengthFieldPrepender"> <constructor-arg value="4"/> </bean> <bean id="string-encoder" class="io.netty.handler.codec.string.StringEncoder"/> <bean id="length-decoder" class="org.apache.camel.component.netty4.ChannelHandlerFactories" factory-method="newLengthFieldBasedFrameDecoder"> <constructor-arg value="1048576"/> <constructor-arg value="0"/> <constructor-arg value="4"/> <constructor-arg value="0"/> <constructor-arg value="4"/> </bean> <bean id="string-decoder" class="io.netty.handler.codec.string.StringDecoder"/> {code} |
The bean names can then be used in netty endpoint definitions either as a comma separated list or contained in a List e.g..g.
Code Block |
---|
Wiki Markup |
{code} from("direct:multiple-codec").to("netty4:tcp://localhost:{{port}}?encoders=#encoders&sync=false"); from("netty4:tcp://localhost:{{port}}?decoders=#length-decoder,#string-decoder&sync=false").to("mock:multiple-codec"); {code} |
or via spring.
Code Block |
---|
Wiki Markup |
{code} <camelContext id="multiple-netty-codecs-context" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:multiple-codec"/> <to uri="netty4:tcp://localhost:5150?encoders=#encoders&sync=false"/> </route> <route> <from uri="netty4:tcp://localhost:5150?decoders=#length-decoder,#string-decoder&sync=false"/> <to uri="mock:multiple-codec"/> </route> </camelContext> {code} |
Closing Channel When Complete
...
Adding custom channel pipeline factories to gain complete control over a created pipeline
Available as of Camel 2.5
Custom channel pipelines provide complete control to the user over the handler/interceptor chain by inserting custom handler(s), encoder(s) & decoders without having to specify them in the Netty Endpoint URL in a very simple way.
...
- A Producer linked channel pipeline factory must extend the abstract class
ClientPipelineFactory
. - A Consumer linked channel pipeline factory must extend the abstract class
ServerPipelineFactory
ServerInitializerFactory
. - The classes should override the getPipelineinitChannel() method in order to insert custom handler(s), encoder(s) and decoder(s). Not overriding the getPipelineinitChannel() method creates a pipeline with no handlers, encoders or decoders wired to the pipeline.
The example below shows how ServerChannel Pipeline ServerInitializerFactory factory may be created
Code Block | ||
---|---|---|
| ||
public class SampleServerChannelPipelineFactorySampleServerInitializerFactory extends ServerPipelineFactoryServerInitializerFactory { private int maxLineSize = 1024; public protected ChannelPipelinevoid getPipelineinitChannel(Channel ch) throws Exception { ChannelPipeline channelPipeline = Channelsch.pipeline(); channelPipeline.addLast("encoder-SD", new StringEncoder(CharsetUtil.UTF_8)); channelPipeline.addLast("decoder-DELIM", new DelimiterBasedFrameDecoder(maxLineSize, true, Delimiters.lineDelimiter())); channelPipeline.addLast("decoder-SD", new StringDecoder(CharsetUtil.UTF_8)); // here we add the default Camel ServerChannelHandler for the consumer, to allow Camel to route the message etc. channelPipeline.addLast("handler", new ServerChannelHandler(consumer)); return channelPipeline; } } |
The custom channel pipeline factory can then be added to the registry and instantiated/utilized on a camel route in the following way
Code Block |
---|
Registry registry = camelContext.getRegistry(); serverPipelineFactoryServerInitializerFactory factory = new TestServerChannelPipelineFactoryTestServerInitializerFactory(); registry.bind("spf", serverPipelineFactoryfactory); context.addRoutes(new RouteBuilder() { public void configure() { String netty_ssl_endpoint = "netty4:tcp://localhost:5150?serverPipelineFactoryserverInitializerFactory=#spf" String return_string = "When You Go Home, Tell Them Of Us And Say," + "For Your Tomorrow, We Gave Our Today."; from(netty_ssl_endpoint) .process(new Processor() { public void process(Exchange exchange) throws Exception { exchange.getOut().setBody(return_string); } } } }); |
...