Updated Branches: refs/heads/master b20999969 -> 0d4357174
CAMEL-6327: More work on new camel-netty-http component. Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/0d435717 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/0d435717 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/0d435717 Branch: refs/heads/master Commit: 0d435717420120a68b6b3438af0f226f579dabb9 Parents: b209999 Author: Claus Ibsen <davscl...@apache.org> Authored: Wed Jun 19 12:01:54 2013 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Wed Jun 19 12:01:54 2013 +0200 ---------------------------------------------------------------------- .../netty/http/HttpServerBootstrapFactory.java | 15 ++- .../netty/http/NettyHttpComponent.java | 1 - ...outesValidateBootstrapConfigurationTest.java | 52 +++++++++ .../component/netty/NettyConfiguration.java | 1 + .../NettyServerBootstrapConfiguration.java | 117 +++++++++++++++++++ 5 files changed, 184 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/0d435717/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/HttpServerBootstrapFactory.java ---------------------------------------------------------------------- diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/HttpServerBootstrapFactory.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/HttpServerBootstrapFactory.java index 223ccdb..e1168d7 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/HttpServerBootstrapFactory.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/HttpServerBootstrapFactory.java @@ -19,6 +19,7 @@ package org.apache.camel.component.netty.http; import org.apache.camel.CamelContext; import org.apache.camel.component.netty.NettyConfiguration; import org.apache.camel.component.netty.NettyConsumer; +import org.apache.camel.component.netty.NettyServerBootstrapConfiguration; import org.apache.camel.component.netty.SingleTCPNettyServerBootstrapFactory; import org.jboss.netty.channel.ChannelPipelineFactory; import org.slf4j.Logger; @@ -29,6 +30,7 @@ public class HttpServerBootstrapFactory extends SingleTCPNettyServerBootstrapFac private static final Logger LOG = LoggerFactory.getLogger(HttpServerBootstrapFactory.class); private final NettyHttpComponent component; private int port; + private NettyServerBootstrapConfiguration bootstrapConfiguration; public HttpServerBootstrapFactory(NettyHttpComponent component) { this.component = component; @@ -38,11 +40,22 @@ public class HttpServerBootstrapFactory extends SingleTCPNettyServerBootstrapFac public void init(CamelContext camelContext, NettyConfiguration configuration, ChannelPipelineFactory pipelineFactory) { super.init(camelContext, configuration, pipelineFactory); this.port = configuration.getPort(); + this.bootstrapConfiguration = configuration; - LOG.info("BootstrapFactory on port {} is using configuration: {}", port, configuration); + LOG.info("BootstrapFactory on port {} is using bootstrap configuration: [{}]", port, bootstrapConfiguration.toStringBootstrapConfiguration()); } public void addConsumer(NettyConsumer consumer) { + // when adding additional consumers on the same port (eg to reuse port for multiple routes etc) then the Netty server bootstrap + // configuration must match, as its the 1st consumer that calls the init method, which configuration is used for the Netty server bootstrap + // we do this to avoid mis configuration, so people configure SSL and plain configuration on the same port etc. + + // first it may be the same instance, so only check for compatibility of different instance + if (bootstrapConfiguration != consumer.getConfiguration() && !bootstrapConfiguration.compatible(consumer.getConfiguration())) { + throw new IllegalArgumentException("Bootstrap configuration must be identical when adding additional consumer: " + consumer.getEndpoint() + " on same port: " + port + + ".\n Existing " + bootstrapConfiguration.toStringBootstrapConfiguration() + "\n New " + consumer.getConfiguration().toStringBootstrapConfiguration()); + } + if (LOG.isDebugEnabled()) { NettyHttpConsumer httpConsumer = (NettyHttpConsumer) consumer; LOG.debug("BootstrapFactory on port {} is adding consumer with context-path {}", port, httpConsumer.getConfiguration().getPath()); http://git-wip-us.apache.org/repos/asf/camel/blob/0d435717/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpComponent.java ---------------------------------------------------------------------- diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpComponent.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpComponent.java index e76f524..1b0c57c 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpComponent.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpComponent.java @@ -36,7 +36,6 @@ import org.apache.camel.util.UnsafeUriCharactersEncoder; public class NettyHttpComponent extends NettyComponent implements HeaderFilterStrategyAware { // TODO: support on consumer - // - validate routes on same port cannot have different SSL etc // - urlrewrite private final Map<Integer, HttpServerMultiplexChannelHandler> multiplexChannelHandlers = new HashMap<Integer, HttpServerMultiplexChannelHandler>(); http://git-wip-us.apache.org/repos/asf/camel/blob/0d435717/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpTwoRoutesValidateBootstrapConfigurationTest.java ---------------------------------------------------------------------- diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpTwoRoutesValidateBootstrapConfigurationTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpTwoRoutesValidateBootstrapConfigurationTest.java new file mode 100644 index 0000000..77813cb --- /dev/null +++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpTwoRoutesValidateBootstrapConfigurationTest.java @@ -0,0 +1,52 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.netty.http; + +import org.apache.camel.builder.RouteBuilder; +import org.junit.Test; + +public class NettyHttpTwoRoutesValidateBootstrapConfigurationTest extends BaseNettyTest { + + @Override + public boolean isUseRouteBuilder() { + return false; + } + + @Test + public void testTwoRoutes() throws Exception { + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + from("netty-http:http://0.0.0.0:{{port}}/foo") + .to("mock:foo") + .transform().constant("Bye World"); + + // we cannot have a 2nd route on same port with SSL enabled, when the 1st route is NOT + from("netty-http:http://0.0.0.0:{{port}}/bar?ssl=true") + .to("mock:bar") + .transform().constant("Bye Camel"); + } + }); + try { + context.start(); + fail("Should have thrown exception"); + } catch (IllegalArgumentException e) { + assertTrue(e.getMessage().startsWith("Bootstrap configuration must be identical when adding additional consumer")); + } + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/0d435717/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java b/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java index 7ebefdc..0c1fa0e 100644 --- a/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java +++ b/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java @@ -133,6 +133,7 @@ public class NettyConfiguration extends NettyServerBootstrapConfiguration implem setHost(uri.getHost()); setPort(uri.getPort()); + ssl = component.getAndRemoveParameter(parameters, "ssl", boolean.class, false); sslHandler = component.resolveAndRemoveReferenceParameter(parameters, "sslHandler", SslHandler.class, sslHandler); passphrase = component.getAndRemoveParameter(parameters, "passphrase", String.class, passphrase); keyStoreFormat = component.getAndRemoveParameter(parameters, "keyStoreFormat", String.class, keyStoreFormat == null ? "JKS" : keyStoreFormat); http://git-wip-us.apache.org/repos/asf/camel/blob/0d435717/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyServerBootstrapConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyServerBootstrapConfiguration.java b/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyServerBootstrapConfiguration.java index cbcfcae..7542e8e 100644 --- a/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyServerBootstrapConfiguration.java +++ b/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyServerBootstrapConfiguration.java @@ -273,4 +273,121 @@ public class NettyServerBootstrapConfiguration implements Cloneable { public void setOptions(Map<String, Object> options) { this.options = options; } + + /** + * Checks if the other {@link NettyServerBootstrapConfiguration} is compatible + * with this, as a Netty listener bound on port X shares the same common + * {@link NettyServerBootstrapConfiguration}, which must be identical. + */ + public boolean compatible(NettyServerBootstrapConfiguration other) { + if (!protocol.equals(other.protocol)) { + return false; + } + if (!host.equals(other.host)) { + return false; + } + if (port != other.port) { + return false; + } + if (broadcast != other.broadcast) { + return false; + } + if (sendBufferSize != other.sendBufferSize) { + return false; + } + if (receiveBufferSize != other.receiveBufferSize) { + return false; + } + if (receiveBufferSizePredictor != other.receiveBufferSizePredictor) { + return false; + } + if (workerCount != other.workerCount) { + return false; + } + if (keepAlive != other.keepAlive) { + return false; + } + if (tcpNoDelay != other.tcpNoDelay) { + return false; + } + if (reuseAddress != other.reuseAddress) { + return false; + } + if (connectTimeout != other.connectTimeout) { + return false; + } + if (backlog != other.backlog) { + return false; + } + if (serverPipelineFactory != other.serverPipelineFactory) { + return false; + } + if (nettyServerBootstrapFactory != other.nettyServerBootstrapFactory) { + return false; + } + // TODO: compare all the options + + if (ssl != other.ssl) { + return false; + } + if (sslHandler != other.sslHandler) { + return false; + } + if (needClientAuth != other.needClientAuth) { + return false; + } + if (keyStoreFile != other.keyStoreFile) { + return false; + } + if (trustStoreFile != other.trustStoreFile) { + return false; + } + if (keyStoreResource != null && !keyStoreResource.equals(other.keyStoreResource)) { + return false; + } + if (trustStoreResource != null && !trustStoreResource.equals(other.trustStoreResource)) { + return false; + } + if (keyStoreFormat != null && !keyStoreFormat.equals(other.keyStoreFormat)) { + return false; + } + if (securityProvider != null && !securityProvider.equals(other.securityProvider)) { + return false; + } + if (passphrase != null && !passphrase.equals(other.passphrase)) { + return false; + } + return true; + } + + public String toStringBootstrapConfiguration() { + return "NettyServerBootstrapConfiguration{" + + "protocol='" + protocol + '\'' + + ", host='" + host + '\'' + + ", port=" + port + + ", broadcast=" + broadcast + + ", sendBufferSize=" + sendBufferSize + + ", receiveBufferSize=" + receiveBufferSize + + ", receiveBufferSizePredictor=" + receiveBufferSizePredictor + + ", workerCount=" + workerCount + + ", keepAlive=" + keepAlive + + ", tcpNoDelay=" + tcpNoDelay + + ", reuseAddress=" + reuseAddress + + ", connectTimeout=" + connectTimeout + + ", backlog=" + backlog + + ", serverPipelineFactory=" + serverPipelineFactory + + ", nettyServerBootstrapFactory=" + nettyServerBootstrapFactory + + ", options=" + options + + ", ssl=" + ssl + + ", sslHandler=" + sslHandler + + ", needClientAuth=" + needClientAuth + + ", keyStoreFile=" + keyStoreFile + + ", trustStoreFile=" + trustStoreFile + + ", keyStoreResource='" + keyStoreResource + '\'' + + ", trustStoreResource='" + trustStoreResource + '\'' + + ", keyStoreFormat='" + keyStoreFormat + '\'' + + ", securityProvider='" + securityProvider + '\'' + + ", passphrase='" + passphrase + '\'' + + '}'; + } }