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 }