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.jboss.netty.bootstrap.ConnectionlessBootstrap; 026 import org.jboss.netty.bootstrap.ServerBootstrap; 027 import org.jboss.netty.channel.Channel; 028 import org.jboss.netty.channel.ChannelFactory; 029 import org.jboss.netty.channel.group.ChannelGroup; 030 import org.jboss.netty.channel.group.ChannelGroupFuture; 031 import org.jboss.netty.channel.group.DefaultChannelGroup; 032 import org.jboss.netty.channel.socket.DatagramChannelFactory; 033 import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory; 034 import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; 035 import org.slf4j.Logger; 036 import org.slf4j.LoggerFactory; 037 038 public class NettyConsumer extends DefaultConsumer { 039 private static final transient Logger LOG = LoggerFactory.getLogger(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 LOG.debug("Netty consumer binding to: {}", configuration.getAddress()); 064 065 super.doStart(); 066 if (isTcp()) { 067 initializeTCPServerSocketCommunicationLayer(); 068 } else { 069 initializeUDPServerSocketCommunicationLayer(); 070 } 071 072 LOG.info("Netty consumer bound to: " + configuration.getAddress()); 073 } 074 075 @Override 076 protected void doStop() throws Exception { 077 LOG.debug("Netty consumer unbinding from: {}", configuration.getAddress()); 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 LOG.info("Netty consumer unbound from: " + configuration.getAddress()); 091 } 092 093 public CamelContext getContext() { 094 return context; 095 } 096 097 public ChannelGroup getAllChannels() { 098 return allChannels; 099 } 100 101 public NettyConfiguration getConfiguration() { 102 return configuration; 103 } 104 105 public void setConfiguration(NettyConfiguration configuration) { 106 this.configuration = configuration; 107 } 108 109 public ChannelFactory getChannelFactory() { 110 return channelFactory; 111 } 112 113 public void setChannelFactory(ChannelFactory channelFactory) { 114 this.channelFactory = channelFactory; 115 } 116 117 public DatagramChannelFactory getDatagramChannelFactory() { 118 return datagramChannelFactory; 119 } 120 121 public void setDatagramChannelFactory(DatagramChannelFactory datagramChannelFactory) { 122 this.datagramChannelFactory = datagramChannelFactory; 123 } 124 125 public ServerBootstrap getServerBootstrap() { 126 return serverBootstrap; 127 } 128 129 public void setServerBootstrap(ServerBootstrap serverBootstrap) { 130 this.serverBootstrap = serverBootstrap; 131 } 132 133 public ConnectionlessBootstrap getConnectionlessServerBootstrap() { 134 return connectionlessServerBootstrap; 135 } 136 137 public void setConnectionlessServerBootstrap(ConnectionlessBootstrap connectionlessServerBootstrap) { 138 this.connectionlessServerBootstrap = connectionlessServerBootstrap; 139 } 140 141 protected boolean isTcp() { 142 return configuration.getProtocol().equalsIgnoreCase("tcp"); 143 } 144 145 private void initializeTCPServerSocketCommunicationLayer() throws Exception { 146 ExecutorService bossExecutor = context.getExecutorServiceStrategy().newThreadPool(this, "NettyTCPBoss", 147 configuration.getCorePoolSize(), configuration.getMaxPoolSize()); 148 ExecutorService workerExecutor = context.getExecutorServiceStrategy().newThreadPool(this, "NettyTCPWorker", 149 configuration.getCorePoolSize(), configuration.getMaxPoolSize()); 150 151 if (configuration.getWorkerCount() == 0) { 152 channelFactory = new NioServerSocketChannelFactory(bossExecutor, workerExecutor); 153 } else { 154 channelFactory = new NioServerSocketChannelFactory(bossExecutor, workerExecutor, 155 configuration.getWorkerCount()); 156 } 157 serverBootstrap = new ServerBootstrap(channelFactory); 158 if (configuration.getServerPipelineFactory() != null) { 159 configuration.getServerPipelineFactory().setConsumer(this); 160 serverBootstrap.setPipelineFactory(configuration.getServerPipelineFactory()); 161 } else { 162 serverBootstrap.setPipelineFactory(new DefaultServerPipelineFactory(this)); 163 } 164 serverBootstrap.setOption("child.keepAlive", configuration.isKeepAlive()); 165 serverBootstrap.setOption("child.tcpNoDelay", configuration.isTcpNoDelay()); 166 serverBootstrap.setOption("child.reuseAddress", configuration.isReuseAddress()); 167 serverBootstrap.setOption("child.connectTimeoutMillis", configuration.getConnectTimeout()); 168 169 channel = serverBootstrap.bind(new InetSocketAddress(configuration.getHost(), configuration.getPort())); 170 // to keep track of all channels in use 171 allChannels.add(channel); 172 } 173 174 private void initializeUDPServerSocketCommunicationLayer() throws Exception { 175 ExecutorService workerExecutor = context.getExecutorServiceStrategy().newThreadPool(this, "NettyUDPWorker", 176 configuration.getCorePoolSize(), configuration.getMaxPoolSize()); 177 178 datagramChannelFactory = new NioDatagramChannelFactory(workerExecutor); 179 connectionlessServerBootstrap = new ConnectionlessBootstrap(datagramChannelFactory); 180 if (configuration.getServerPipelineFactory() != null) { 181 configuration.getServerPipelineFactory().setConsumer(this); 182 connectionlessServerBootstrap.setPipelineFactory(configuration.getServerPipelineFactory()); 183 } else { 184 connectionlessServerBootstrap.setPipelineFactory(new DefaultServerPipelineFactory(this)); 185 } 186 connectionlessServerBootstrap.setOption("child.keepAlive", configuration.isKeepAlive()); 187 connectionlessServerBootstrap.setOption("child.tcpNoDelay", configuration.isTcpNoDelay()); 188 connectionlessServerBootstrap.setOption("child.reuseAddress", configuration.isReuseAddress()); 189 connectionlessServerBootstrap.setOption("child.connectTimeoutMillis", configuration.getConnectTimeout()); 190 connectionlessServerBootstrap.setOption("child.broadcast", configuration.isBroadcast()); 191 connectionlessServerBootstrap.setOption("sendBufferSize", configuration.getSendBufferSize()); 192 connectionlessServerBootstrap.setOption("receiveBufferSize", configuration.getReceiveBufferSize()); 193 194 channel = connectionlessServerBootstrap.bind(new InetSocketAddress(configuration.getHost(), configuration.getPort())); 195 // to keep track of all channels in use 196 allChannels.add(channel); 197 } 198 199 }