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