Author: davsclaus
Date: Sat Dec 15 11:34:58 2012
New Revision: 1422224
URL: http://svn.apache.org/viewvc?rev=1422224&view=rev
Log:
CAMEL-5687: Fixed jetty to not always create a http client, even if a producer
is newer in use. Removed the danger of using shared http clients, which makes
lifecycle of these harder. Instead made it easier to configure individual http
client thread pool sizes per endpoint instead.
Modified:
camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpEndpoint.java
camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java
Modified:
camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
URL:
http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java?rev=1422224&r1=1422223&r2=1422224&view=diff
==============================================================================
---
camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
(original)
+++
camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
Sat Dec 15 11:34:58 2012
@@ -59,7 +59,6 @@ import org.eclipse.jetty.servlet.FilterH
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlets.MultiPartFilter;
-import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ThreadPool;
import org.slf4j.Logger;
@@ -88,8 +87,6 @@ public class JettyHttpComponent extends
protected Map<Integer, SelectChannelConnector> socketConnectors;
protected Map<String, Object> sslSocketConnectorProperties;
protected Map<String, Object> socketConnectorProperties;
- protected HttpClient httpClient;
- protected ThreadPool httpClientThreadPool;
protected Integer httpClientMinThreads;
protected Integer httpClientMaxThreads;
protected Integer minThreads;
@@ -101,7 +98,6 @@ public class JettyHttpComponent extends
protected Long continuationTimeout;
protected boolean useContinuation = true;
protected SSLContextParameters sslContextParameters;
- protected boolean isExplicitHttpClient;
class ConnectorRef {
Server server;
@@ -150,44 +146,24 @@ public class JettyHttpComponent extends
Boolean useContinuation = getAndRemoveParameter(parameters,
"useContinuation", Boolean.class);
String httpMethodRestrict = getAndRemoveParameter(parameters,
"httpMethodRestrict", String.class);
SSLContextParameters sslContextParameters =
resolveAndRemoveReferenceParameter(parameters, "sslContextParametersRef",
SSLContextParameters.class);
-
-
+ SSLContextParameters ssl = sslContextParameters != null ?
sslContextParameters : this.sslContextParameters;
+
// configure http client if we have url configuration for it
// http client is only used for jetty http producer (hence not very
commonly used)
HttpClient client = null;
if (IntrospectionSupport.hasProperties(parameters, "httpClient.") ||
sslContextParameters != null) {
- client = getNewHttpClient();
-
+ client = createHttpClient(httpClientMinThreads,
httpClientMaxThreads, ssl);
+
if (IntrospectionSupport.hasProperties(parameters, "httpClient."))
{
- if (isExplicitHttpClient) {
- LOG.warn("The user explicitly set an HttpClient instance
on the component, "
- + "but this endpoint provides HttpClient
configuration. Are you sure that "
- + "this is what was intended? Applying endpoint
configuration to a new HttpClient instance "
- + "to avoid altering existing HttpClient
instances.");
- }
-
// set additional parameters on http client
IntrospectionSupport.setProperties(client, parameters,
"httpClient.");
// validate that we could resolve all httpClient. parameters
as this component is lenient
validateParameters(uri, parameters, "httpClient.");
}
- // Note that the component level instance is already configured in
getNewHttpClient.
- // We replace it here for endpoint level config.
- if (sslContextParameters != null) {
- if (isExplicitHttpClient) {
- LOG.warn("The user explicitly set an HttpClient instance
on the component, "
- + "but this endpoint provides
SSLContextParameters configuration. Are you sure that "
- + "this is what was intended? Applying endpoint
configuration to a new HttpClient instance "
- + "to avoid altering existing HttpClient
instances.");
- }
-
- ((CamelHttpClient)
client).setSSLContext(sslContextParameters.createSSLContext());
+ if (ssl != null) {
+ ((CamelHttpClient)
client).setSSLContext(ssl.createSSLContext());
}
- } else {
- // Either we use the default one created by the component or we
are using
- // one explicitly set by the end user, either way, we just use it
as is.
- client = getHttpClient();
}
// keep the configure parameters for the http client
for (String key : parameters.keySet()) {
@@ -247,12 +223,10 @@ public class JettyHttpComponent extends
}
endpoint.setEnableMultipartFilter(enableMultipartFilter);
-
if (multipartFilter != null) {
endpoint.setMultipartFilter(multipartFilter);
endpoint.setEnableMultipartFilter(true);
}
-
if (filters != null) {
endpoint.setFilters(filters);
}
@@ -263,15 +237,12 @@ public class JettyHttpComponent extends
if (useContinuation != null) {
endpoint.setUseContinuation(useContinuation);
}
-
if (httpMethodRestrict != null) {
endpoint.setHttpMethodRestrict(httpMethodRestrict);
}
-
- if (sslContextParameters == null) {
- sslContextParameters = this.sslContextParameters;
+ if (ssl != null) {
+ endpoint.setSslContextParameters(ssl);
}
- endpoint.setSslContextParameters(sslContextParameters);
setProperties(endpoint, parameters);
return endpoint;
@@ -648,14 +619,15 @@ public class JettyHttpComponent extends
this.socketConnectors = socketConnectors;
}
- public synchronized HttpClient getHttpClient() throws Exception {
- if (httpClient == null) {
- httpClient = this.getNewHttpClient();
- }
- return httpClient;
- }
-
- public CamelHttpClient getNewHttpClient() throws Exception {
+ /**
+ * Creates a new {@link HttpClient} and configures its proxy/thread pool
and SSL based on this
+ * component settings.
+ *
+ * @param minThreads optional minimum number of threads in client thread
pool
+ * @param maxThreads optional maximum number of threads in client thread
pool
+ * @param ssl option SSL parameters
+ */
+ public static CamelHttpClient createHttpClient(Integer minThreads, Integer
maxThreads, SSLContextParameters ssl) throws Exception {
CamelHttpClient httpClient = new CamelHttpClient();
httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
@@ -668,15 +640,18 @@ public class JettyHttpComponent extends
httpClient.setProxy(new Address(host, port));
}
- // use QueueThreadPool as the default bounded is deprecated (see
SMXCOMP-157)
- if (getHttpClientThreadPool() == null) {
- QueuedThreadPool qtp = new QueuedThreadPool();
- if (httpClientMinThreads != null) {
- qtp.setMinThreads(httpClientMinThreads.intValue());
- }
- if (httpClientMaxThreads != null) {
- qtp.setMaxThreads(httpClientMaxThreads.intValue());
+ // must have both min and max
+ if (minThreads != null || maxThreads != null) {
+
+ // must have both options
+ if (minThreads == null || maxThreads == null) {
+ throw new IllegalArgumentException("Both min and max thread
pool sizes must be provided.");
}
+
+ // use QueueThreadPool as the default bounded is deprecated (see
SMXCOMP-157)
+ QueuedThreadPool qtp = new QueuedThreadPool();
+ qtp.setMinThreads(minThreads.intValue());
+ qtp.setMaxThreads(maxThreads.intValue());
// let the thread names indicate they are from the client
qtp.setName("CamelJettyClient(" +
ObjectHelper.getIdentityHashCode(httpClient) + ")");
try {
@@ -684,32 +659,22 @@ public class JettyHttpComponent extends
} catch (Exception e) {
throw new RuntimeCamelException("Error starting
JettyHttpClient thread pool: " + qtp, e);
}
- setHttpClientThreadPool(qtp);
+ httpClient.setThreadPool(qtp);
}
- httpClient.setThreadPool(getHttpClientThreadPool());
-
- if (this.sslContextParameters != null) {
-
httpClient.setSSLContext(this.sslContextParameters.createSSLContext());
- }
-
- return httpClient;
- }
- public void setHttpClient(HttpClient httpClient) {
- if (httpClient != null) {
- this.isExplicitHttpClient = true;
- } else {
- this.isExplicitHttpClient = false;
+ if (ssl != null) {
+ httpClient.setSSLContext(ssl.createSSLContext());
}
- this.httpClient = httpClient;
- }
-
- public ThreadPool getHttpClientThreadPool() {
- return httpClientThreadPool;
- }
- public void setHttpClientThreadPool(ThreadPool httpClientThreadPool) {
- this.httpClientThreadPool = httpClientThreadPool;
+ if (LOG.isDebugEnabled()) {
+ if (minThreads != null) {
+ LOG.debug("Created HttpClient with thread pool {}-{} -> {}",
new Object[]{minThreads, maxThreads, httpClient});
+ } else {
+ LOG.debug("Created HttpClient with default thread pool size ->
{}", httpClient);
+ }
+ }
+
+ return httpClient;
}
public Integer getHttpClientMinThreads() {
@@ -953,14 +918,6 @@ public class JettyHttpComponent extends
@Override
protected void doStart() throws Exception {
super.doStart();
- if (httpClientThreadPool != null && httpClientThreadPool instanceof
LifeCycle) {
- LifeCycle lc = (LifeCycle) httpClientThreadPool;
- lc.start();
- }
- if (httpClient != null && !httpClient.isStarted()) {
- httpClient.start();
- }
-
startMbContainer();
}
@@ -984,15 +941,9 @@ public class JettyHttpComponent extends
}
}
}
- if (httpClient != null) {
- httpClient.stop();
- }
- if (httpClientThreadPool != null && httpClientThreadPool instanceof
LifeCycle) {
- LifeCycle lc = (LifeCycle) httpClientThreadPool;
- lc.stop();
- }
if (mbContainer != null) {
mbContainer.stop();
+ mbContainer = null;
}
}
}
Modified:
camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpEndpoint.java
URL:
http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpEndpoint.java?rev=1422224&r1=1422223&r2=1422224&view=diff
==============================================================================
---
camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpEndpoint.java
(original)
+++
camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpEndpoint.java
Sat Dec 15 11:34:58 2012
@@ -19,7 +19,6 @@ package org.apache.camel.component.jetty
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
-
import javax.servlet.Filter;
import org.apache.camel.Consumer;
@@ -40,6 +39,8 @@ public class JettyHttpEndpoint extends H
private boolean sessionSupport;
private List<Handler> handlers;
private HttpClient client;
+ private Integer httpClientMinThreads;
+ private Integer httpClientMaxThreads;
private JettyHttpBinding jettyBinding;
private boolean enableJmx;
private boolean enableMultipartFilter;
@@ -60,7 +61,17 @@ public class JettyHttpEndpoint extends H
@Override
public Producer createProducer() throws Exception {
- JettyHttpProducer answer = new JettyHttpProducer(this, getClient());
+ JettyHttpProducer answer = new JettyHttpProducer(this);
+ if (client != null) {
+ // use shared client
+ answer.setSharedClient(client);
+ } else {
+ // create a new client
+ // thread pool min/max from endpoint take precedence over from
component
+ Integer min = httpClientMinThreads != null ? httpClientMinThreads
: getComponent().getHttpClientMinThreads();
+ Integer max = httpClientMaxThreads != null ? httpClientMaxThreads
: getComponent().getHttpClientMaxThreads();
+ answer.setClient(JettyHttpComponent.createHttpClient(min, max,
sslContextParameters));
+ }
answer.setBinding(getJettyBinding());
if (isSynchronous()) {
return new SynchronousDelegateProducer(answer);
@@ -91,12 +102,16 @@ public class JettyHttpEndpoint extends H
}
public HttpClient getClient() throws Exception {
- if (client == null) {
- return getComponent().getHttpClient();
- }
return client;
}
+ /**
+ * Sets a shared {@link HttpClient} to use for all producers
+ * created by this endpoint. By default each producer will
+ * use a new http client, and not share.
+ * <p/>
+ * This options should only be used in special circumstances.
+ */
public void setClient(HttpClient client) {
this.client = client;
}
@@ -170,4 +185,20 @@ public class JettyHttpEndpoint extends H
public void setSslContextParameters(SSLContextParameters
sslContextParameters) {
this.sslContextParameters = sslContextParameters;
}
+
+ @Override
+ protected void doStart() throws Exception {
+ if (client != null) {
+ client.start();
+ }
+ super.doStart();
+ }
+
+ @Override
+ protected void doStop() throws Exception {
+ super.doStop();
+ if (client != null) {
+ client.stop();
+ }
+ }
}
Modified:
camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java
URL:
http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java?rev=1422224&r1=1422223&r2=1422224&view=diff
==============================================================================
---
camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java
(original)
+++
camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java
Sat Dec 15 11:34:58 2012
@@ -52,13 +52,31 @@ import org.slf4j.LoggerFactory;
*/
public class JettyHttpProducer extends DefaultProducer implements
AsyncProcessor {
private static final transient Logger LOG =
LoggerFactory.getLogger(JettyHttpProducer.class);
- private final HttpClient client;
+ private HttpClient client;
+ private boolean sharedClient;
private JettyHttpBinding binding;
+ /**
+ * Creates this producer.
+ * <p/>
+ * A client must be set before use, eg either {@link
#setClient(org.eclipse.jetty.client.HttpClient)}
+ * or {@link #setSharedClient(org.eclipse.jetty.client.HttpClient)}.
+ *
+ * @param endpoint the endpoint
+ */
+ public JettyHttpProducer(Endpoint endpoint) {
+ super(endpoint);
+ }
+
+ /**
+ * Creates this producer
+ *
+ * @param endpoint the endpoint
+ * @param client the non-shared client to use
+ */
public JettyHttpProducer(Endpoint endpoint, HttpClient client) {
super(endpoint);
- this.client = client;
- ObjectHelper.notNull(client, "HttpClient", this);
+ setClient(client);
}
@Override
@@ -240,15 +258,43 @@ public class JettyHttpProducer extends D
this.binding = binding;
}
+ public HttpClient getClient() {
+ return client;
+ }
+
+ public void setClient(HttpClient client) {
+ this.client = client;
+ this.sharedClient = false;
+ }
+
+ public HttpClient getSharedClient() {
+ if (sharedClient) {
+ return client;
+ } else {
+ return null;
+ }
+ }
+
+ public void setSharedClient(HttpClient sharedClient) {
+ this.client = sharedClient;
+ this.sharedClient = true;
+ }
+
@Override
protected void doStart() throws Exception {
- client.start();
+ // only start non-shared client
+ if (!sharedClient && client != null) {
+ client.start();
+ }
super.doStart();
}
@Override
protected void doStop() throws Exception {
super.doStop();
- client.stop();
+ // only stop non-shared client
+ if (!sharedClient && client != null) {
+ client.stop();
+ }
}
}