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 }