/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.camel.component.netty; import java.net.InetSocketAddress; import java.nio.charset.Charset; import java.util.concurrent.Executors; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.Channels; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.SimpleChannelHandler; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; import org.jboss.netty.handler.codec.frame.Delimiters; import org.jboss.netty.util.CharsetUtil; import org.junit.Test; public class NettyConsumerClientModeTest extends BaseNettyTest { private static final ChannelBuffer DATA = ChannelBuffers.copiedBuffer("Willem".getBytes(CharsetUtil.UTF_8)); private MyServer server; public void startNettyServer() { server = new MyServer(getPort()); server.start(); } public void shutdownServer() { if (server != null) { server.shutdown(); } } @Test public void testNettyRoute() throws Exception { try { startNettyServer(); MockEndpoint receive = context.getEndpoint("mock:receive", MockEndpoint.class); receive.expectedBodiesReceived("Bye Willem"); context.startRoute("client"); receive.assertIsSatisfied(); } finally { shutdownServer(); } } @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("netty:tcp://localhost:{{port}}?textline=true&clientMode=true").id("client") .process(new Processor() { public void process(final Exchange exchange) { String body = exchange.getIn().getBody(String.class); exchange.getOut().setBody("Bye " + body); } }).to("mock:receive").noAutoStartup(); } }; } private static class MyServer { private int port; private ServerBootstrap bootstrap; MyServer(int port) { this.port = port; } public void start() { // Configure the server. bootstrap = new ServerBootstrap( new NioServerSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); // Set up the event pipeline factory. bootstrap.setPipelineFactory(new ServerPipelineFactory()); // Bind and start to accept incoming connections. bootstrap.bind(new InetSocketAddress(port)); } public void shutdown() { bootstrap.shutdown(); } } private static class ServerHandler extends SimpleChannelHandler { @Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) { Channel ch = e.getChannel(); ch.write(DATA); ChannelFuture f = ch.write(Delimiters.lineDelimiter()[0]); f.addListener(new ChannelFutureListener() { public void operationComplete(ChannelFuture future) { Channel ch = future.getChannel(); ch.close(); } }); } @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { e.getCause().printStackTrace(); e.getChannel().close(); } } private static class ServerPipelineFactory implements ChannelPipelineFactory { public ChannelPipeline getPipeline() { ChannelPipeline p = Channels.pipeline(); Charset charset = CharsetUtil.UTF_8; ChannelBuffer[] delimiters = Delimiters.nulDelimiter(); // setup the textline encoding and decoding p.addLast("decoder1", ChannelHandlerFactories.newDelimiterBasedFrameDecoder(1024 * 8, delimiters).newChannelHandler()); p.addLast("decoder2", ChannelHandlerFactories.newStringDecoder(charset).newChannelHandler()); p.addLast("encoder", ChannelHandlerFactories.newStringEncoder(charset).newChannelHandler()); p.addLast("handler", new ServerHandler()); return p; } } }