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.io.File;
020 import java.net.URI;
021 import java.nio.charset.Charset;
022 import java.util.ArrayList;
023 import java.util.List;
024 import java.util.Map;
025
026 import org.apache.camel.LoggingLevel;
027 import org.apache.camel.RuntimeCamelException;
028 import org.apache.camel.util.EndpointHelper;
029 import org.jboss.netty.channel.ChannelDownstreamHandler;
030 import org.jboss.netty.channel.ChannelUpstreamHandler;
031 import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
032 import org.jboss.netty.handler.codec.frame.Delimiters;
033 import org.jboss.netty.handler.codec.serialization.ObjectDecoder;
034 import org.jboss.netty.handler.codec.serialization.ObjectEncoder;
035 import org.jboss.netty.handler.codec.string.StringDecoder;
036 import org.jboss.netty.handler.codec.string.StringEncoder;
037 import org.jboss.netty.handler.ssl.SslHandler;
038 import org.jboss.netty.util.CharsetUtil;
039 import org.slf4j.Logger;
040 import org.slf4j.LoggerFactory;
041
042 @SuppressWarnings("unchecked")
043 public class NettyConfiguration implements Cloneable {
044 private static final transient Logger LOG = LoggerFactory.getLogger(NettyConfiguration.class);
045
046 private String protocol;
047 private String host;
048 private int port;
049 private boolean keepAlive = true;
050 private boolean tcpNoDelay = true;
051 private boolean broadcast;
052 private long connectTimeout = 10000;
053 private boolean reuseAddress = true;
054 private boolean sync = true;
055 private boolean textline;
056 private TextLineDelimiter delimiter = TextLineDelimiter.LINE;
057 private boolean autoAppendDelimiter = true;
058 private int decoderMaxLineLength = 1024;
059 private String encoding;
060 private String passphrase;
061 private File keyStoreFile;
062 private File trustStoreFile;
063 private SslHandler sslHandler;
064 private List<ChannelDownstreamHandler> encoders = new ArrayList<ChannelDownstreamHandler>();
065 private List<ChannelUpstreamHandler> decoders = new ArrayList<ChannelUpstreamHandler>();
066 private boolean ssl;
067 private long sendBufferSize = 65536;
068 private long receiveBufferSize = 65536;
069 private int corePoolSize = 10;
070 private int maxPoolSize = 100;
071 private String keyStoreFormat;
072 private String securityProvider;
073 private boolean disconnect;
074 private boolean lazyChannelCreation = true;
075 private boolean transferExchange;
076 private boolean disconnectOnNoReply = true;
077 private LoggingLevel noReplyLogLevel = LoggingLevel.WARN;
078 private boolean allowDefaultCodec = true;
079 private ClientPipelineFactory clientPipelineFactory;
080 private ServerPipelineFactory serverPipelineFactory;
081
082 /**
083 * Returns a copy of this configuration
084 */
085 public NettyConfiguration copy() {
086 try {
087 NettyConfiguration answer = (NettyConfiguration) clone();
088 // make sure the lists is copied in its own instance
089 List<ChannelDownstreamHandler> encodersCopy = new ArrayList<ChannelDownstreamHandler>(encoders);
090 answer.setEncoders(encodersCopy);
091 List<ChannelUpstreamHandler> decodersCopy = new ArrayList<ChannelUpstreamHandler>(decoders);
092 answer.setDecoders(decodersCopy);
093 return answer;
094 } catch (CloneNotSupportedException e) {
095 throw new RuntimeCamelException(e);
096 }
097 }
098
099 public void parseURI(URI uri, Map<String, Object> parameters, NettyComponent component) throws Exception {
100 protocol = uri.getScheme();
101
102 if ((!protocol.equalsIgnoreCase("tcp")) && (!protocol.equalsIgnoreCase("udp"))) {
103 throw new IllegalArgumentException("Unrecognized Netty protocol: " + protocol + " for uri: " + uri);
104 }
105
106 setHost(uri.getHost());
107 setPort(uri.getPort());
108
109 sslHandler = component.resolveAndRemoveReferenceParameter(parameters, "sslHandler", SslHandler.class, null);
110 passphrase = component.resolveAndRemoveReferenceParameter(parameters, "passphrase", String.class, null);
111 keyStoreFormat = component.getAndRemoveParameter(parameters, "keyStoreFormat", String.class, "JKS");
112 securityProvider = component.getAndRemoveParameter(parameters, "securityProvider", String.class, "SunX509");
113 keyStoreFile = component.resolveAndRemoveReferenceParameter(parameters, "keyStoreFile", File.class, null);
114 trustStoreFile = component.resolveAndRemoveReferenceParameter(parameters, "trustStoreFile", File.class, null);
115 clientPipelineFactory = component.resolveAndRemoveReferenceParameter(parameters, "clientPipelineFactory", ClientPipelineFactory.class, null);
116 serverPipelineFactory = component.resolveAndRemoveReferenceParameter(parameters, "serverPipelineFactory", ServerPipelineFactory.class, null);
117
118 // set custom encoders and decoders first
119 List<ChannelDownstreamHandler> referencedEncoders = component.resolveAndRemoveReferenceListParameter(parameters, "encoders", ChannelDownstreamHandler.class, null);
120 addToHandlersList(encoders, referencedEncoders, ChannelDownstreamHandler.class);
121 List<ChannelUpstreamHandler> referencedDecoders = component.resolveAndRemoveReferenceListParameter(parameters, "decoders", ChannelUpstreamHandler.class, null);
122 addToHandlersList(decoders, referencedDecoders, ChannelUpstreamHandler.class);
123
124 // then set parameters with the help of the camel context type converters
125 EndpointHelper.setProperties(component.getCamelContext(), this, parameters);
126
127 // add default encoders and decoders
128 if (encoders.isEmpty() && decoders.isEmpty()) {
129 if (allowDefaultCodec) {
130 // are we textline or object?
131 if (isTextline()) {
132 Charset charset = getEncoding() != null ? Charset.forName(getEncoding()) : CharsetUtil.UTF_8;
133 encoders.add(new StringEncoder(charset));
134 decoders.add(new DelimiterBasedFrameDecoder(decoderMaxLineLength, true, delimiter == TextLineDelimiter.LINE ? Delimiters.lineDelimiter() : Delimiters.nulDelimiter()));
135 decoders.add(new StringDecoder(charset));
136
137 if (LOG.isDebugEnabled()) {
138 LOG.debug("Using textline encoders and decoders with charset: " + charset + ", delimiter: "
139 + delimiter + " and decoderMaxLineLength: " + decoderMaxLineLength);
140 }
141 } else {
142 // object serializable is then used
143 encoders.add(new ObjectEncoder());
144 decoders.add(new ObjectDecoder());
145
146 if (LOG.isDebugEnabled()) {
147 LOG.debug("Using object encoders and decoders");
148 }
149 }
150 } else {
151 if (LOG.isDebugEnabled()) {
152 LOG.debug("No encoders and decoders will be used");
153 }
154 }
155 } else {
156 LOG.debug("Using configured encoders and/or decoders");
157 }
158 }
159
160 public String getCharsetName() {
161 if (encoding == null) {
162 return null;
163 }
164 if (!Charset.isSupported(encoding)) {
165 throw new IllegalArgumentException("The encoding: " + encoding + " is not supported");
166 }
167
168 return Charset.forName(encoding).name();
169 }
170
171 public boolean isTcp() {
172 return protocol.equalsIgnoreCase("tcp");
173 }
174
175 public String getProtocol() {
176 return protocol;
177 }
178
179 public void setProtocol(String protocol) {
180 this.protocol = protocol;
181 }
182
183 public String getHost() {
184 return host;
185 }
186
187 public void setHost(String host) {
188 this.host = host;
189 }
190
191 public int getPort() {
192 return port;
193 }
194
195 public void setPort(int port) {
196 this.port = port;
197 }
198
199 public boolean isKeepAlive() {
200 return keepAlive;
201 }
202
203 public void setKeepAlive(boolean keepAlive) {
204 this.keepAlive = keepAlive;
205 }
206
207 public boolean isTcpNoDelay() {
208 return tcpNoDelay;
209 }
210
211 public void setTcpNoDelay(boolean tcpNoDelay) {
212 this.tcpNoDelay = tcpNoDelay;
213 }
214
215 public boolean isBroadcast() {
216 return broadcast;
217 }
218
219 public void setBroadcast(boolean broadcast) {
220 this.broadcast = broadcast;
221 }
222
223 public long getConnectTimeout() {
224 return connectTimeout;
225 }
226
227 public void setConnectTimeout(long connectTimeout) {
228 this.connectTimeout = connectTimeout;
229 }
230
231 public boolean isReuseAddress() {
232 return reuseAddress;
233 }
234
235 public void setReuseAddress(boolean reuseAddress) {
236 this.reuseAddress = reuseAddress;
237 }
238
239 public boolean isSync() {
240 return sync;
241 }
242
243 public void setSync(boolean sync) {
244 this.sync = sync;
245 }
246
247 public boolean isTextline() {
248 return textline;
249 }
250
251 public void setTextline(boolean textline) {
252 this.textline = textline;
253 }
254
255 public int getDecoderMaxLineLength() {
256 return decoderMaxLineLength;
257 }
258
259 public void setDecoderMaxLineLength(int decoderMaxLineLength) {
260 this.decoderMaxLineLength = decoderMaxLineLength;
261 }
262
263 public TextLineDelimiter getDelimiter() {
264 return delimiter;
265 }
266
267 public void setDelimiter(TextLineDelimiter delimiter) {
268 this.delimiter = delimiter;
269 }
270
271 public boolean isAutoAppendDelimiter() {
272 return autoAppendDelimiter;
273 }
274
275 public void setAutoAppendDelimiter(boolean autoAppendDelimiter) {
276 this.autoAppendDelimiter = autoAppendDelimiter;
277 }
278
279 public String getEncoding() {
280 return encoding;
281 }
282
283 public void setEncoding(String encoding) {
284 this.encoding = encoding;
285 }
286
287 public SslHandler getSslHandler() {
288 return sslHandler;
289 }
290
291 public void setSslHandler(SslHandler sslHandler) {
292 this.sslHandler = sslHandler;
293 }
294
295 public List<ChannelDownstreamHandler> getEncoders() {
296 return encoders;
297 }
298
299 public List<ChannelUpstreamHandler> getDecoders() {
300 return decoders;
301 }
302
303 public ChannelDownstreamHandler getEncoder() {
304 return encoders.isEmpty() ? null : encoders.get(0);
305 }
306
307 public void setEncoder(ChannelDownstreamHandler encoder) {
308 if (!encoders.contains(encoder)) {
309 encoders.add(encoder);
310 }
311 }
312
313 public void setEncoders(List<ChannelDownstreamHandler> encoders) {
314 this.encoders = encoders;
315 }
316
317 public ChannelUpstreamHandler getDecoder() {
318 return decoders.isEmpty() ? null : decoders.get(0);
319 }
320
321 public void setDecoder(ChannelUpstreamHandler decoder) {
322 if (!decoders.contains(decoder)) {
323 decoders.add(decoder);
324 }
325 }
326
327 public void setDecoders(List<ChannelUpstreamHandler> decoders) {
328 this.decoders = decoders;
329 }
330
331 public long getSendBufferSize() {
332 return sendBufferSize;
333 }
334
335 public void setSendBufferSize(long sendBufferSize) {
336 this.sendBufferSize = sendBufferSize;
337 }
338
339 public boolean isSsl() {
340 return ssl;
341 }
342
343 public void setSsl(boolean ssl) {
344 this.ssl = ssl;
345 }
346
347 public long getReceiveBufferSize() {
348 return receiveBufferSize;
349 }
350
351 public void setReceiveBufferSize(long receiveBufferSize) {
352 this.receiveBufferSize = receiveBufferSize;
353 }
354
355 public String getPassphrase() {
356 return passphrase;
357 }
358
359 public void setPassphrase(String passphrase) {
360 this.passphrase = passphrase;
361 }
362
363 public File getKeyStoreFile() {
364 return keyStoreFile;
365 }
366
367 public void setKeyStoreFile(File keyStoreFile) {
368 this.keyStoreFile = keyStoreFile;
369 }
370
371 public File getTrustStoreFile() {
372 return trustStoreFile;
373 }
374
375 public void setTrustStoreFile(File trustStoreFile) {
376 this.trustStoreFile = trustStoreFile;
377 }
378
379 public int getCorePoolSize() {
380 return corePoolSize;
381 }
382
383 public void setCorePoolSize(int corePoolSize) {
384 this.corePoolSize = corePoolSize;
385 }
386
387 public int getMaxPoolSize() {
388 return maxPoolSize;
389 }
390
391 public void setMaxPoolSize(int maxPoolSize) {
392 this.maxPoolSize = maxPoolSize;
393 }
394
395 public String getKeyStoreFormat() {
396 return keyStoreFormat;
397 }
398
399 public void setKeyStoreFormat(String keyStoreFormat) {
400 this.keyStoreFormat = keyStoreFormat;
401 }
402
403 public String getSecurityProvider() {
404 return securityProvider;
405 }
406
407 public void setSecurityProvider(String securityProvider) {
408 this.securityProvider = securityProvider;
409 }
410
411 public boolean isDisconnect() {
412 return disconnect;
413 }
414
415 public void setDisconnect(boolean disconnect) {
416 this.disconnect = disconnect;
417 }
418
419 public boolean isLazyChannelCreation() {
420 return lazyChannelCreation;
421 }
422
423 public void setLazyChannelCreation(boolean lazyChannelCreation) {
424 this.lazyChannelCreation = lazyChannelCreation;
425 }
426
427 public boolean isTransferExchange() {
428 return transferExchange;
429 }
430
431 public void setTransferExchange(boolean transferExchange) {
432 this.transferExchange = transferExchange;
433 }
434
435 public boolean isDisconnectOnNoReply() {
436 return disconnectOnNoReply;
437 }
438
439 public void setDisconnectOnNoReply(boolean disconnectOnNoReply) {
440 this.disconnectOnNoReply = disconnectOnNoReply;
441 }
442
443 public LoggingLevel getNoReplyLogLevel() {
444 return noReplyLogLevel;
445 }
446
447 public void setNoReplyLogLevel(LoggingLevel noReplyLogLevel) {
448 this.noReplyLogLevel = noReplyLogLevel;
449 }
450
451 public boolean isAllowDefaultCodec() {
452 return allowDefaultCodec;
453 }
454
455 public void setAllowDefaultCodec(boolean allowDefaultCodec) {
456 this.allowDefaultCodec = allowDefaultCodec;
457 }
458
459 public String getAddress() {
460 return host + ":" + port;
461 }
462
463 private <T> void addToHandlersList(List configured, List handlers, Class<? extends T> handlerType) {
464 if (handlers != null) {
465 for (int x = 0; x < handlers.size(); x++) {
466 Object handler = handlers.get(x);
467 if (handlerType.isInstance(handler)) {
468 configured.add(handler);
469 }
470 }
471 }
472 }
473
474 public void setClientPipelineFactory(ClientPipelineFactory clientPipelineFactory) {
475 this.clientPipelineFactory = clientPipelineFactory;
476 }
477
478 public ClientPipelineFactory getClientPipelineFactory() {
479 return clientPipelineFactory;
480 }
481
482 public void setServerPipelineFactory(ServerPipelineFactory serverPipelineFactory) {
483 this.serverPipelineFactory = serverPipelineFactory;
484 }
485
486 public ServerPipelineFactory getServerPipelineFactory() {
487 return serverPipelineFactory;
488 }
489
490 }