001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.component.netty;
018
019 import java.net.InetSocketAddress;
020 import java.util.concurrent.ExecutorService;
021
022 import org.apache.camel.CamelContext;
023 import org.apache.camel.Processor;
024 import org.apache.camel.impl.DefaultConsumer;
025 import org.apache.commons.logging.Log;
026 import org.apache.commons.logging.LogFactory;
027 import org.jboss.netty.bootstrap.ConnectionlessBootstrap;
028 import org.jboss.netty.bootstrap.ServerBootstrap;
029 import org.jboss.netty.channel.Channel;
030 import org.jboss.netty.channel.ChannelFactory;
031 import org.jboss.netty.channel.group.ChannelGroup;
032 import org.jboss.netty.channel.group.ChannelGroupFuture;
033 import org.jboss.netty.channel.group.DefaultChannelGroup;
034 import org.jboss.netty.channel.socket.DatagramChannelFactory;
035 import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory;
036 import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
037
038 public class NettyConsumer extends DefaultConsumer {
039 private static final transient Log LOG = LogFactory.getLog(NettyConsumer.class);
040 private final ChannelGroup allChannels;
041 private CamelContext context;
042 private NettyConfiguration configuration;
043 private ChannelFactory channelFactory;
044 private DatagramChannelFactory datagramChannelFactory;
045 private ServerBootstrap serverBootstrap;
046 private ConnectionlessBootstrap connectionlessServerBootstrap;
047 private Channel channel;
048
049 public NettyConsumer(NettyEndpoint nettyEndpoint, Processor processor, NettyConfiguration configuration) {
050 super(nettyEndpoint, processor);
051 this.context = this.getEndpoint().getCamelContext();
052 this.configuration = configuration;
053 this.allChannels = new DefaultChannelGroup("NettyProducer-" + nettyEndpoint.getEndpointUri());
054 }
055
056 @Override
057 public NettyEndpoint getEndpoint() {
058 return (NettyEndpoint) super.getEndpoint();
059 }
060
061 @Override
062 protected void doStart() throws Exception {
063 super.doStart();
064 if (configuration.getProtocol().equalsIgnoreCase("udp")) {
065 initializeUDPServerSocketCommunicationLayer();
066 } else {
067 initializeTCPServerSocketCommunicationLayer();
068 }
069
070 LOG.info("Netty consumer bound to: " + configuration.getAddress());
071 }
072
073 @Override
074 protected void doStop() throws Exception {
075 if (LOG.isInfoEnabled()) {
076 LOG.info("Netty consumer unbinding from: " + configuration.getAddress());
077 }
078
079 // close all channels
080 ChannelGroupFuture future = allChannels.close();
081 future.awaitUninterruptibly();
082
083 // and then release other resources
084 if (channelFactory != null) {
085 channelFactory.releaseExternalResources();
086 }
087
088 super.doStop();
089 }
090
091 public ChannelGroup getAllChannels() {
092 return allChannels;
093 }
094
095 public NettyConfiguration getConfiguration() {
096 return configuration;
097 }
098
099 public void setConfiguration(NettyConfiguration configuration) {
100 this.configuration = configuration;
101 }
102
103 public ChannelFactory getChannelFactory() {
104 return channelFactory;
105 }
106
107 public void setChannelFactory(ChannelFactory channelFactory) {
108 this.channelFactory = channelFactory;
109 }
110
111 public DatagramChannelFactory getDatagramChannelFactory() {
112 return datagramChannelFactory;
113 }
114
115 public void setDatagramChannelFactory(DatagramChannelFactory datagramChannelFactory) {
116 this.datagramChannelFactory = datagramChannelFactory;
117 }
118
119 public ServerBootstrap getServerBootstrap() {
120 return serverBootstrap;
121 }
122
123 public void setServerBootstrap(ServerBootstrap serverBootstrap) {
124 this.serverBootstrap = serverBootstrap;
125 }
126
127 public ConnectionlessBootstrap getConnectionlessServerBootstrap() {
128 return connectionlessServerBootstrap;
129 }
130
131 public void setConnectionlessServerBootstrap(ConnectionlessBootstrap connectionlessServerBootstrap) {
132 this.connectionlessServerBootstrap = connectionlessServerBootstrap;
133 }
134
135 private void initializeTCPServerSocketCommunicationLayer() throws Exception {
136 ExecutorService bossExecutor = context.getExecutorServiceStrategy().newThreadPool(this, "NettyTCPBoss",
137 configuration.getCorePoolSize(), configuration.getMaxPoolSize());
138 ExecutorService workerExecutor = context.getExecutorServiceStrategy().newThreadPool(this, "NettyTCPWorker",
139 configuration.getCorePoolSize(), configuration.getMaxPoolSize());
140
141 channelFactory = new NioServerSocketChannelFactory(bossExecutor, workerExecutor);
142 serverBootstrap = new ServerBootstrap(channelFactory);
143 serverBootstrap.setPipelineFactory(new ServerPipelineFactory(this));
144 serverBootstrap.setOption("child.keepAlive", configuration.isKeepAlive());
145 serverBootstrap.setOption("child.tcpNoDelay", configuration.isTcpNoDelay());
146 serverBootstrap.setOption("child.reuseAddress", configuration.isReuseAddress());
147 serverBootstrap.setOption("child.connectTimeoutMillis", configuration.getConnectTimeout());
148
149 channel = serverBootstrap.bind(new InetSocketAddress(configuration.getHost(), configuration.getPort()));
150 // to keep track of all channels in use
151 allChannels.add(channel);
152 }
153
154 private void initializeUDPServerSocketCommunicationLayer() throws Exception {
155 ExecutorService workerExecutor = context.getExecutorServiceStrategy().newThreadPool(this, "NettyUDPWorker",
156 configuration.getCorePoolSize(), configuration.getMaxPoolSize());
157
158 datagramChannelFactory = new NioDatagramChannelFactory(workerExecutor);
159 connectionlessServerBootstrap = new ConnectionlessBootstrap(datagramChannelFactory);
160 connectionlessServerBootstrap.setPipelineFactory(new ServerPipelineFactory(this));
161 connectionlessServerBootstrap.setOption("child.keepAlive", configuration.isKeepAlive());
162 connectionlessServerBootstrap.setOption("child.tcpNoDelay", configuration.isTcpNoDelay());
163 connectionlessServerBootstrap.setOption("child.reuseAddress", configuration.isReuseAddress());
164 connectionlessServerBootstrap.setOption("child.connectTimeoutMillis", configuration.getConnectTimeout());
165 connectionlessServerBootstrap.setOption("child.broadcast", configuration.isBroadcast());
166 connectionlessServerBootstrap.setOption("sendBufferSize", configuration.getSendBufferSize());
167 connectionlessServerBootstrap.setOption("receiveBufferSize", configuration.getReceiveBufferSize());
168
169 channel = connectionlessServerBootstrap.bind(new InetSocketAddress(configuration.getHost(), configuration.getPort()));
170 // to keep track of all channels in use
171 allChannels.add(channel);
172 }
173
174 }