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