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