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