You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2016/04/22 08:29:59 UTC
[1/2] camel git commit: CAMEL-6707: fix issues reported by @davsclaus
Repository: camel
Updated Branches:
refs/heads/master 2bd185e92 -> e6da66a69
CAMEL-6707: fix issues reported by @davsclaus
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/e6da66a6
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/e6da66a6
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/e6da66a6
Branch: refs/heads/master
Commit: e6da66a69840d8aa5ab1926974a92b779f90c868
Parents: 6a1f84e
Author: Arnaud Deprez <ar...@lampiris.be>
Authored: Thu Apr 21 22:13:03 2016 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Fri Apr 22 07:44:45 2016 +0200
----------------------------------------------------------------------
.../websocket/CamelWebSocketServlet.java | 8 +--
.../apache/camel/http/common/CamelServlet.java | 53 +++++++-------
.../camel/http/common/DefaultHttpBinding.java | 62 ++++++++++------
.../camel/http/common/HttpCommonComponent.java | 1 +
.../camel/http/common/HttpCommonEndpoint.java | 16 +++--
.../jetty/CamelContinuationServlet.java | 23 +++---
.../component/jetty/JettyHttpComponent.java | 76 ++++++++++++++------
.../jetty/ExplicitJettyAsyncRouteTest.java | 2 +-
...pHttpMessageFormUrlEncodedFalseBodyTest.java | 6 +-
.../component/jetty/HttpBridgeRouteTest.java | 4 +-
.../component/jetty/HttpsAsyncRouteTest.java | 16 ++---
.../camel/component/jetty/HttpsRouteTest.java | 20 +++---
.../component/servlet/ServletComponent.java | 17 ++---
.../component/servlet/ServletEndpoint.java | 6 +-
.../servlet/ServletAsyncArquillianTest.java | 72 +++++++++++--------
15 files changed, 227 insertions(+), 155 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/e6da66a6/components/camel-atmosphere-websocket/src/main/java/org/apache/camel/component/atmosphere/websocket/CamelWebSocketServlet.java
----------------------------------------------------------------------
diff --git a/components/camel-atmosphere-websocket/src/main/java/org/apache/camel/component/atmosphere/websocket/CamelWebSocketServlet.java b/components/camel-atmosphere-websocket/src/main/java/org/apache/camel/component/atmosphere/websocket/CamelWebSocketServlet.java
index 2a84a73..9ddb21a 100644
--- a/components/camel-atmosphere-websocket/src/main/java/org/apache/camel/component/atmosphere/websocket/CamelWebSocketServlet.java
+++ b/components/camel-atmosphere-websocket/src/main/java/org/apache/camel/component/atmosphere/websocket/CamelWebSocketServlet.java
@@ -16,14 +16,14 @@
*/
package org.apache.camel.component.atmosphere.websocket;
-import org.apache.camel.component.servlet.CamelHttpTransportServlet;
-import org.apache.camel.http.common.HttpConsumer;
-
+import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
+
+import org.apache.camel.component.servlet.CamelHttpTransportServlet;
+import org.apache.camel.http.common.HttpConsumer;
/**
* This servlet is used to add some websocket specific handling at the moment.
http://git-wip-us.apache.org/repos/asf/camel/blob/e6da66a6/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelServlet.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelServlet.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelServlet.java
index 382a6a4..ed94745 100644
--- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelServlet.java
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelServlet.java
@@ -16,6 +16,18 @@
*/
package org.apache.camel.http.common;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.servlet.AsyncContext;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.RuntimeCamelException;
@@ -24,25 +36,12 @@ import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.servlet.AsyncContext;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
/**
* A servlet to use as a Camel route as entry.
*/
public class CamelServlet extends HttpServlet {
- private static final long serialVersionUID = -7061982839117697829L;
public static final String ASYNC_PARAM = "async";
+ private static final long serialVersionUID = -7061982839117697829L;
protected final Logger log = LoggerFactory.getLogger(getClass());
/**
@@ -50,7 +49,7 @@ public class CamelServlet extends HttpServlet {
* sure that it is already set via the init method
*/
private String servletName;
- private boolean async = false;
+ private boolean async;
private ServletResolveConsumerStrategy servletResolveConsumerStrategy = new HttpServletResolveConsumerStrategy();
private final ConcurrentMap<String, HttpConsumer> consumers = new ConcurrentHashMap<String, HttpConsumer>();
@@ -59,9 +58,9 @@ public class CamelServlet extends HttpServlet {
public void init(ServletConfig config) throws ServletException {
super.init(config);
this.servletName = config.getServletName();
- this.async = Optional.ofNullable(config.getInitParameter(ASYNC_PARAM))
- .map(ObjectHelper::toBoolean)
- .orElse(Boolean.FALSE);
+
+ final String asyncParam = config.getInitParameter(ASYNC_PARAM);
+ this.async = asyncParam == null ? false : ObjectHelper.toBoolean(asyncParam);
log.trace("servlet '{}' initialized with: async={}", new Object[]{servletName, async});
}
@@ -71,13 +70,12 @@ public class CamelServlet extends HttpServlet {
final AsyncContext context = req.startAsync();
//run async
context.start(() -> doServiceAsync(context));
- }
- else {
+ } else {
doService(req, resp);
}
}
- /**
+ /**
* This is used to handle request asynchronously
* @param context the {@link AsyncContext}
*/
@@ -86,25 +84,22 @@ public class CamelServlet extends HttpServlet {
final HttpServletResponse response = (HttpServletResponse) context.getResponse();
try {
doService(request, response);
- }
- //An error shouldn't occur as we should handle most of error in doService
- catch (Exception e) {
+ } catch (Exception e) {
+ //An error shouldn't occur as we should handle most of error in doService
log.error("Error processing request", e);
try {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- }
- catch (Exception e1) {
+ } catch (Exception e1) {
log.debug("Cannot send reply to client!", e1);
}
//Need to wrap it in RuntimeException as it occurs in a Runnable
throw new RuntimeCamelException(e);
- }
- finally {
+ } finally {
context.complete();
}
}
- /**
+ /**
* This is the logical implementation to handle request with {@link CamelServlet}
* This is where most exceptions should be handled
*
http://git-wip-us.apache.org/repos/asf/camel/blob/e6da66a6/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
index 1f190fe..828d90c 100644
--- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
@@ -16,7 +16,34 @@
*/
package org.apache.camel.http.common;
-import org.apache.camel.*;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+import javax.activation.DataHandler;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.InvalidPayloadException;
+import org.apache.camel.Message;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.StreamCache;
import org.apache.camel.converter.stream.CachedOutputStream;
import org.apache.camel.spi.HeaderFilterStrategy;
import org.apache.camel.util.GZIPHelper;
@@ -26,15 +53,6 @@ import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.activation.DataHandler;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.*;
-import java.net.URLDecoder;
-import java.text.SimpleDateFormat;
-import java.util.*;
-
/**
* Binding between {@link HttpMessage} and {@link HttpServletResponse}.
* <p/>
@@ -92,11 +110,11 @@ public class DefaultHttpBinding implements HttpBinding {
readHeaders(request, message);
}
if (mapHttpMessageFormUrlEncodedBody) {
- try {
- readFormUrlEncodedBody(request, message);
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeCamelException("Cannot read Form URL encoded body due " + e.getMessage(), e);
- }
+ try {
+ readFormUrlEncodedBody(request, message);
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeCamelException("Cannot read Form URL encoded body due " + e.getMessage(), e);
+ }
}
// populate the headers from the request
@@ -212,9 +230,9 @@ public class DefaultHttpBinding implements HttpBinding {
}
}
- protected void readFormUrlEncodedBody(HttpServletRequest request, HttpMessage message) throws UnsupportedEncodingException {
+ protected void readFormUrlEncodedBody(HttpServletRequest request, HttpMessage message) throws UnsupportedEncodingException {
LOG.trace("readFormUrlEncodedBody {}", request);
- // should we extract key=value pairs from form bodies (application/x-www-form-urlencoded)
+ // should we extract key=value pairs from form bodies (application/x-www-form-urlencoded)
// and map those to Camel headers
if (mapHttpMessageBody && mapHttpMessageHeaders) {
LOG.trace("HTTP method {} with Content-Type {}", request.getMethod(), request.getContentType());
@@ -260,16 +278,16 @@ public class DefaultHttpBinding implements HttpBinding {
}
}
}
- }
+ }
private String getRawPath(HttpServletRequest request) {
String uri = request.getRequestURI();
- /**
+ /**
* In async case, it seems that request.getContextPath() can return null
* @see https://dev.eclipse.org/mhonarc/lists/jetty-users/msg04669.html
*/
- String contextPath = Optional.ofNullable(request.getContextPath()).orElse("");
- String servletPath = Optional.ofNullable(request.getServletPath()).orElse("");
+ String contextPath = request.getContextPath() == null ? "" : request.getContextPath();
+ String servletPath = request.getServletPath() == null ? "" : request.getServletPath();
return uri.substring(contextPath.length() + servletPath.length());
}
@@ -619,7 +637,7 @@ public class DefaultHttpBinding implements HttpBinding {
this.mapHttpMessageFormUrlEncodedBody = mapHttpMessageFormUrlEncodedBody;
}
- protected static SimpleDateFormat getHttpDateFormat() {
+ protected static SimpleDateFormat getHttpDateFormat() {
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT, Locale.US);
dateFormat.setTimeZone(TIME_ZONE_GMT);
return dateFormat;
http://git-wip-us.apache.org/repos/asf/camel/blob/e6da66a6/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonComponent.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonComponent.java
index a99472e..189c269 100644
--- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonComponent.java
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonComponent.java
@@ -86,4 +86,5 @@ public abstract class HttpCommonComponent extends HeaderFilterStrategyComponent
public void setAllowJavaSerializedObject(boolean allowJavaSerializedObject) {
this.allowJavaSerializedObject = allowJavaSerializedObject;
}
+
}
http://git-wip-us.apache.org/repos/asf/camel/blob/e6da66a6/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
index 9007322..99f03ea 100644
--- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
@@ -16,12 +16,16 @@
*/
package org.apache.camel.http.common;
-import org.apache.camel.impl.DefaultEndpoint;
-import org.apache.camel.spi.*;
-
import java.net.URI;
import java.net.URISyntaxException;
+import org.apache.camel.impl.DefaultEndpoint;
+import org.apache.camel.spi.HeaderFilterStrategy;
+import org.apache.camel.spi.HeaderFilterStrategyAware;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriPath;
+
public abstract class HttpCommonEndpoint extends DefaultEndpoint implements HeaderFilterStrategyAware {
// Note: all options must be documented with description in annotations so extended components can access the documentation
@@ -43,9 +47,9 @@ public abstract class HttpCommonEndpoint extends DefaultEndpoint implements Head
+ " You may also set the option throwExceptionOnFailure to be false to let the HttpProducer send all the fault response back.")
boolean bridgeEndpoint;
@UriParam(label = "producer",
- description = "If the option is true, HttpProducer will set the Host header to the value contained in the current exchange Host header, " +
- "useful in reverse proxy applications where you want the Host header received by the downstream server to reflect the URL called by the upstream client, " +
- "this allows applications which use the Host header to generate accurate URL's for a proxied service")
+ description = "If the option is true, HttpProducer will set the Host header to the value contained in the current exchange Host header, "
+ + "useful in reverse proxy applications where you want the Host header received by the downstream server to reflect the URL called by the upstream client, "
+ + "this allows applications which use the Host header to generate accurate URL's for a proxied service")
boolean preserveHostHeader;
@UriParam(label = "consumer",
description = "Whether or not the consumer should try to find a target consumer by matching the URI prefix if no exact match is found.")
http://git-wip-us.apache.org/repos/asf/camel/blob/e6da66a6/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java
index d9abfe2..f1299f4 100644
--- a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java
+++ b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java
@@ -16,24 +16,29 @@
*/
package org.apache.camel.component.jetty;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
import org.apache.camel.AsyncCallback;
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
-import org.apache.camel.http.common.*;
+import org.apache.camel.http.common.CamelServlet;
+import org.apache.camel.http.common.HttpCommonEndpoint;
+import org.apache.camel.http.common.HttpConstants;
+import org.apache.camel.http.common.HttpConsumer;
+import org.apache.camel.http.common.HttpHelper;
+import org.apache.camel.http.common.HttpMessage;
import org.apache.camel.impl.DefaultExchange;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.UnsafeUriCharactersEncoder;
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationSupport;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
/**
* Servlet which leverage <a href="http://wiki.eclipse.org/Jetty/Feature/Continuations">Jetty Continuations</a>.
*
http://git-wip-us.apache.org/repos/asf/camel/blob/e6da66a6/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
index 828514b..7b3e7bf 100644
--- a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
+++ b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
@@ -16,16 +16,61 @@
*/
package org.apache.camel.component.jetty;
-import org.apache.camel.*;
-import org.apache.camel.http.common.*;
-import org.apache.camel.spi.*;
-import org.apache.camel.util.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import javax.management.MBeanServer;
+import javax.servlet.Filter;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Consumer;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Processor;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.http.common.CamelServlet;
+import org.apache.camel.http.common.HttpBinding;
+import org.apache.camel.http.common.HttpCommonComponent;
+import org.apache.camel.http.common.HttpCommonEndpoint;
+import org.apache.camel.http.common.HttpConfiguration;
+import org.apache.camel.http.common.HttpConsumer;
+import org.apache.camel.http.common.HttpRestServletResolveConsumerStrategy;
+import org.apache.camel.http.common.UrlRewrite;
+import org.apache.camel.spi.HeaderFilterStrategy;
+import org.apache.camel.spi.ManagementAgent;
+import org.apache.camel.spi.ManagementStrategy;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.RestApiConsumerFactory;
+import org.apache.camel.spi.RestConfiguration;
+import org.apache.camel.spi.RestConsumerFactory;
+import org.apache.camel.util.FileUtil;
+import org.apache.camel.util.HostUtils;
+import org.apache.camel.util.IntrospectionSupport;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.URISupport;
+import org.apache.camel.util.UnsafeUriCharactersEncoder;
import org.apache.camel.util.jsse.SSLContextParameters;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.jmx.MBeanContainer;
-import org.eclipse.jetty.server.*;
+import org.eclipse.jetty.server.AbstractConnector;
+import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
@@ -43,21 +88,6 @@ import org.eclipse.jetty.util.thread.ThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.management.MBeanServer;
-import javax.servlet.Filter;
-import javax.servlet.RequestDispatcher;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.IOException;
-import java.io.Writer;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.GeneralSecurityException;
-import java.util.*;
-
/**
* An HttpComponent which starts an embedded Jetty for to handle consuming from
* the http endpoints.
@@ -152,7 +182,7 @@ public abstract class JettyHttpComponent extends HttpCommonComponent implements
Integer httpClientMinThreads = getAndRemoveParameter(parameters, "httpClientMinThreads", Integer.class, this.httpClientMinThreads);
Integer httpClientMaxThreads = getAndRemoveParameter(parameters, "httpClientMaxThreads", Integer.class, this.httpClientMaxThreads);
HttpClient httpClient = resolveAndRemoveReferenceParameter(parameters, "httpClient", HttpClient.class);
- Optional<Boolean> async = Optional.ofNullable(getAndRemoveParameter(parameters, "async", Boolean.class));
+ Boolean async = getAndRemoveParameter(parameters, "async", Boolean.class);
// extract httpClient. parameters
Map<String, Object> httpClientParameters = IntrospectionSupport.extractProperties(parameters, "httpClient.");
@@ -174,7 +204,9 @@ public abstract class JettyHttpComponent extends HttpCommonComponent implements
endpointUri = new URI(scheme + ":" + endpointUri);
JettyHttpEndpoint endpoint = createEndpoint(endpointUri, httpUri);
- async.ifPresent(endpoint::setAsync);
+ if (async != null) {
+ endpoint.setAsync(async);
+ }
if (headerFilterStrategy != null) {
endpoint.setHeaderFilterStrategy(headerFilterStrategy);
http://git-wip-us.apache.org/repos/asf/camel/blob/e6da66a6/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/ExplicitJettyAsyncRouteTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/ExplicitJettyAsyncRouteTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/ExplicitJettyAsyncRouteTest.java
index 63fba47..8b36461 100644
--- a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/ExplicitJettyAsyncRouteTest.java
+++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/ExplicitJettyAsyncRouteTest.java
@@ -16,12 +16,12 @@
*/
package org.apache.camel.component.jetty;
+import javax.servlet.http.HttpServletRequest;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.junit.Test;
-import javax.servlet.http.HttpServletRequest;
/**
* Unit test for wiki demonstration.
http://git-wip-us.apache.org/repos/asf/camel/blob/e6da66a6/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBindingMapHttpMessageFormUrlEncodedFalseBodyTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBindingMapHttpMessageFormUrlEncodedFalseBodyTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBindingMapHttpMessageFormUrlEncodedFalseBodyTest.java
index 0a99d9b..8f3df8d 100644
--- a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBindingMapHttpMessageFormUrlEncodedFalseBodyTest.java
+++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBindingMapHttpMessageFormUrlEncodedFalseBodyTest.java
@@ -29,9 +29,9 @@ public class HttpBindingMapHttpMessageFormUrlEncodedFalseBodyTest extends BaseJe
@Test
public void testSendToJetty() throws Exception {
- Map<String,Object> map = new HashMap<String,Object>();
- map.put("content-type", "application/x-www-form-urlencoded");
- map.put(Exchange.HTTP_METHOD, HttpMethods.POST);
+ Map<String, Object> map = new HashMap<>();
+ map.put("content-type", "application/x-www-form-urlencoded");
+ map.put(Exchange.HTTP_METHOD, HttpMethods.POST);
template.requestBodyAndHeaders("http://localhost:{{port}}/myapp/myservice?query1=a&query2=b", "b1=x&b2=y", map);
}
http://git-wip-us.apache.org/repos/asf/camel/blob/e6da66a6/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeRouteTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeRouteTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeRouteTest.java
index edfbd3a..6b9cf2a 100644
--- a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeRouteTest.java
+++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeRouteTest.java
@@ -16,14 +16,14 @@
*/
package org.apache.camel.component.jetty;
+import java.io.ByteArrayInputStream;
+
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.builder.RouteBuilder;
import org.junit.Test;
-import java.io.ByteArrayInputStream;
-
public class HttpBridgeRouteTest extends BaseJettyTest {
protected int port1;
http://git-wip-us.apache.org/repos/asf/camel/blob/e6da66a6/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsAsyncRouteTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsAsyncRouteTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsAsyncRouteTest.java
index 6e3041b..a9e986e 100644
--- a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsAsyncRouteTest.java
+++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsAsyncRouteTest.java
@@ -16,6 +16,14 @@
*/
package org.apache.camel.component.jetty;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.SocketException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;
@@ -27,14 +35,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.SocketException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.List;
-import java.util.Map;
public class HttpsAsyncRouteTest extends HttpsRouteTest {
http://git-wip-us.apache.org/repos/asf/camel/blob/e6da66a6/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsRouteTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsRouteTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsRouteTest.java
index 9a3e04b..3403897 100644
--- a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsRouteTest.java
+++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsRouteTest.java
@@ -16,6 +16,16 @@
*/
package org.apache.camel.component.jetty;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.SocketException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;
@@ -28,16 +38,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.SocketException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
public class HttpsRouteTest extends BaseJettyTest {
public static final String NULL_VALUE_MARKER = CamelTestSupport.class.getCanonicalName();
http://git-wip-us.apache.org/repos/asf/camel/blob/e6da66a6/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java
index 2a16ebf..161c275 100644
--- a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java
+++ b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java
@@ -16,6 +16,11 @@
*/
package org.apache.camel.component.servlet;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
import org.apache.camel.CamelContext;
import org.apache.camel.Consumer;
import org.apache.camel.Endpoint;
@@ -32,12 +37,6 @@ import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.URISupport;
import org.apache.camel.util.UnsafeUriCharactersEncoder;
-import java.net.URI;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Optional;
-
public class ServletComponent extends HttpCommonComponent implements RestConsumerFactory, RestApiConsumerFactory {
private String servletName = "CamelServlet";
@@ -62,7 +61,7 @@ public class ServletComponent extends HttpCommonComponent implements RestConsume
String servletName = getAndRemoveParameter(parameters, "servletName", String.class, getServletName());
String httpMethodRestrict = getAndRemoveParameter(parameters, "httpMethodRestrict", String.class);
HeaderFilterStrategy headerFilterStrategy = resolveAndRemoveReferenceParameter(parameters, "headerFilterStrategy", HeaderFilterStrategy.class);
- Optional<Boolean> async = Optional.ofNullable(getAndRemoveParameter(parameters, "async", Boolean.class));
+ Boolean async = getAndRemoveParameter(parameters, "async", Boolean.class);
if (lenientContextPath()) {
// the uri must have a leading slash for the context-path matching to work with servlet, and it can be something people
@@ -82,7 +81,9 @@ public class ServletComponent extends HttpCommonComponent implements RestConsume
ServletEndpoint endpoint = createServletEndpoint(uri, this, httpUri);
endpoint.setServletName(servletName);
- async.ifPresent(endpoint::setAsync);
+ if (async != null) {
+ endpoint.setAsync(async);
+ }
if (headerFilterStrategy != null) {
endpoint.setHeaderFilterStrategy(headerFilterStrategy);
} else {
http://git-wip-us.apache.org/repos/asf/camel/blob/e6da66a6/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletEndpoint.java b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletEndpoint.java
index a22ffdb..5beefc3 100644
--- a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletEndpoint.java
+++ b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletEndpoint.java
@@ -16,6 +16,9 @@
*/
package org.apache.camel.component.servlet;
+import java.net.URI;
+import java.net.URISyntaxException;
+
import org.apache.camel.Consumer;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
@@ -25,9 +28,6 @@ import org.apache.camel.spi.UriEndpoint;
import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriPath;
-import java.net.URI;
-import java.net.URISyntaxException;
-
/**
* To use a HTTP Servlet as entry for Camel routes when running in a servlet container.
*/
http://git-wip-us.apache.org/repos/asf/camel/blob/e6da66a6/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletAsyncArquillianTest.java
----------------------------------------------------------------------
diff --git a/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletAsyncArquillianTest.java b/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletAsyncArquillianTest.java
index 8ce0d98..8d50058 100644
--- a/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletAsyncArquillianTest.java
+++ b/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletAsyncArquillianTest.java
@@ -1,5 +1,24 @@
+/**
+ * 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.servlet;
+import java.net.URL;
+import java.nio.file.Paths;
+import java.text.MessageFormat;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
@@ -10,13 +29,10 @@ import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.net.URL;
-import java.nio.file.Paths;
-import java.text.MessageFormat;
-
import static com.jayway.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.equalTo;
+
/**
* @author arnaud.deprez
* @since 18/04/16
@@ -24,29 +40,29 @@ import static org.hamcrest.CoreMatchers.equalTo;
@RunWith(Arquillian.class)
public class ServletAsyncArquillianTest {
- @Deployment
- public static Archive<?> createTestArchive() {
- // this is a WAR project so use WebArchive
- return ShrinkWrap.create(WebArchive.class)
- // add the web.xml
- .setWebXML(Paths.get("src/test/resources/org/apache/camel/component/servlet/web-spring-async.xml").toFile());
- }
+ @Deployment
+ public static Archive<?> createTestArchive() {
+ // this is a WAR project so use WebArchive
+ return ShrinkWrap.create(WebArchive.class)
+ // add the web.xml
+ .setWebXML(Paths.get("src/test/resources/org/apache/camel/component/servlet/web-spring-async.xml").toFile());
+ }
- /**
- *
- * @param url the URL is the URL to the web application that was deployed
- * @throws Exception
- */
- @Test
- @RunAsClient
- public void testHello(@ArquillianResource URL url) throws Exception {
- final String name = "Arnaud";
- given().
- baseUri(url.toString()).
- queryParam("name", name).
- when().
- get("/services/hello").
- then().
- body(equalTo(MessageFormat.format("Hello {0} how are you?", name)));
- }
+ /**
+ *
+ * @param url the URL is the URL to the web application that was deployed
+ * @throws Exception
+ */
+ @Test
+ @RunAsClient
+ public void testHello(@ArquillianResource URL url) throws Exception {
+ final String name = "Arnaud";
+ given().
+ baseUri(url.toString()).
+ queryParam("name", name).
+ when().
+ get("/services/hello").
+ then().
+ body(equalTo(MessageFormat.format("Hello {0} how are you?", name)));
+ }
}
[2/2] camel git commit: CAMEL-6707: add async for servlet
Posted by da...@apache.org.
CAMEL-6707: add async for servlet
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/6a1f84e0
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/6a1f84e0
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/6a1f84e0
Branch: refs/heads/master
Commit: 6a1f84e0bcddb68fcc075613a72b919709f9be3c
Parents: 2bd185e
Author: Arnaud Deprez <ar...@lampiris.be>
Authored: Wed Apr 13 23:38:00 2016 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Fri Apr 22 07:44:45 2016 +0200
----------------------------------------------------------------------
.../websocket/CamelWebSocketServlet.java | 10 +-
.../apache/camel/http/common/CamelServlet.java | 89 +++++++--
.../camel/http/common/DefaultHttpBinding.java | 46 ++---
.../camel/http/common/HttpCommonComponent.java | 1 -
.../camel/http/common/HttpCommonEndpoint.java | 27 ++-
components/camel-http/src/main/docs/http.adoc | 2 +
.../jetty/CamelContinuationServlet.java | 27 ++-
.../component/jetty/JettyHttpComponent.java | 74 +++----
.../jetty/ExplicitJettyAsyncRouteTest.java | 66 +++++++
.../jetty/HttpBridgeAsyncRouteTest.java | 48 +++++
.../component/jetty/HttpBridgeRouteTest.java | 8 +-
.../component/jetty/HttpsAsyncRouteTest.java | 196 +++++++++++++++++++
.../camel/component/jetty/HttpsRouteTest.java | 22 +--
components/camel-servlet/pom.xml | 76 +++++++
.../component/servlet/ServletComponent.java | 13 +-
.../component/servlet/ServletEndpoint.java | 6 +-
.../servlet/ServletAsyncArquillianTest.java | 52 +++++
.../component/servlet/web-spring-async.xml | 56 ++++++
18 files changed, 674 insertions(+), 145 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-atmosphere-websocket/src/main/java/org/apache/camel/component/atmosphere/websocket/CamelWebSocketServlet.java
----------------------------------------------------------------------
diff --git a/components/camel-atmosphere-websocket/src/main/java/org/apache/camel/component/atmosphere/websocket/CamelWebSocketServlet.java b/components/camel-atmosphere-websocket/src/main/java/org/apache/camel/component/atmosphere/websocket/CamelWebSocketServlet.java
index 6c9be21..2a84a73 100644
--- a/components/camel-atmosphere-websocket/src/main/java/org/apache/camel/component/atmosphere/websocket/CamelWebSocketServlet.java
+++ b/components/camel-atmosphere-websocket/src/main/java/org/apache/camel/component/atmosphere/websocket/CamelWebSocketServlet.java
@@ -16,14 +16,14 @@
*/
package org.apache.camel.component.atmosphere.websocket;
-import java.io.IOException;
+import org.apache.camel.component.servlet.CamelHttpTransportServlet;
+import org.apache.camel.http.common.HttpConsumer;
+
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-
-import org.apache.camel.component.servlet.CamelHttpTransportServlet;
-import org.apache.camel.http.common.HttpConsumer;
+import java.io.IOException;
/**
* This servlet is used to add some websocket specific handling at the moment.
@@ -50,7 +50,7 @@ public class CamelWebSocketServlet extends CamelHttpTransportServlet {
}
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ protected void doService(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
log.trace("Service: {}", request);
// Is there a consumer registered for the request.
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelServlet.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelServlet.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelServlet.java
index cd872c6..382a6a4 100644
--- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelServlet.java
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/CamelServlet.java
@@ -16,28 +16,33 @@
*/
package org.apache.camel.http.common;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
+import org.apache.camel.RuntimeCamelException;
import org.apache.camel.impl.DefaultExchange;
+import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.servlet.AsyncContext;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
/**
* A servlet to use as a Camel route as entry.
*/
public class CamelServlet extends HttpServlet {
private static final long serialVersionUID = -7061982839117697829L;
+ public static final String ASYNC_PARAM = "async";
protected final Logger log = LoggerFactory.getLogger(getClass());
/**
@@ -45,6 +50,7 @@ public class CamelServlet extends HttpServlet {
* sure that it is already set via the init method
*/
private String servletName;
+ private boolean async = false;
private ServletResolveConsumerStrategy servletResolveConsumerStrategy = new HttpServletResolveConsumerStrategy();
private final ConcurrentMap<String, HttpConsumer> consumers = new ConcurrentHashMap<String, HttpConsumer>();
@@ -53,10 +59,61 @@ public class CamelServlet extends HttpServlet {
public void init(ServletConfig config) throws ServletException {
super.init(config);
this.servletName = config.getServletName();
+ this.async = Optional.ofNullable(config.getInitParameter(ASYNC_PARAM))
+ .map(ObjectHelper::toBoolean)
+ .orElse(Boolean.FALSE);
+ log.trace("servlet '{}' initialized with: async={}", new Object[]{servletName, async});
}
@Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ protected final void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ if (isAsync()) {
+ final AsyncContext context = req.startAsync();
+ //run async
+ context.start(() -> doServiceAsync(context));
+ }
+ else {
+ doService(req, resp);
+ }
+ }
+
+ /**
+ * This is used to handle request asynchronously
+ * @param context the {@link AsyncContext}
+ */
+ protected void doServiceAsync(AsyncContext context) {
+ final HttpServletRequest request = (HttpServletRequest) context.getRequest();
+ final HttpServletResponse response = (HttpServletResponse) context.getResponse();
+ try {
+ doService(request, response);
+ }
+ //An error shouldn't occur as we should handle most of error in doService
+ catch (Exception e) {
+ log.error("Error processing request", e);
+ try {
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+ catch (Exception e1) {
+ log.debug("Cannot send reply to client!", e1);
+ }
+ //Need to wrap it in RuntimeException as it occurs in a Runnable
+ throw new RuntimeCamelException(e);
+ }
+ finally {
+ context.complete();
+ }
+ }
+
+ /**
+ * This is the logical implementation to handle request with {@link CamelServlet}
+ * This is where most exceptions should be handled
+ *
+ * @param request the {@link HttpServletRequest}
+ * @param response the {@link HttpServletResponse}
+ * @throws ServletException
+ * @throws IOException
+ */
+ protected void doService(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
log.trace("Service: {}", request);
// Is there a consumer registered for the request.
@@ -202,6 +259,14 @@ public class CamelServlet extends HttpServlet {
this.servletResolveConsumerStrategy = servletResolveConsumerStrategy;
}
+ public boolean isAsync() {
+ return async;
+ }
+
+ public void setAsync(boolean async) {
+ this.async = async;
+ }
+
public Map<String, HttpConsumer> getConsumers() {
return Collections.unmodifiableMap(consumers);
}
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
index da361ea..1f190fe 100644
--- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
@@ -16,34 +16,7 @@
*/
package org.apache.camel.http.common;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TimeZone;
-import javax.activation.DataHandler;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.camel.Endpoint;
-import org.apache.camel.Exchange;
-import org.apache.camel.InvalidPayloadException;
-import org.apache.camel.Message;
-import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.StreamCache;
+import org.apache.camel.*;
import org.apache.camel.converter.stream.CachedOutputStream;
import org.apache.camel.spi.HeaderFilterStrategy;
import org.apache.camel.util.GZIPHelper;
@@ -53,6 +26,15 @@ import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.activation.DataHandler;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLDecoder;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
/**
* Binding between {@link HttpMessage} and {@link HttpServletResponse}.
* <p/>
@@ -282,8 +264,12 @@ public class DefaultHttpBinding implements HttpBinding {
private String getRawPath(HttpServletRequest request) {
String uri = request.getRequestURI();
- String contextPath = request.getContextPath();
- String servletPath = request.getServletPath();
+ /**
+ * In async case, it seems that request.getContextPath() can return null
+ * @see https://dev.eclipse.org/mhonarc/lists/jetty-users/msg04669.html
+ */
+ String contextPath = Optional.ofNullable(request.getContextPath()).orElse("");
+ String servletPath = Optional.ofNullable(request.getServletPath()).orElse("");
return uri.substring(contextPath.length() + servletPath.length());
}
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonComponent.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonComponent.java
index 189c269..a99472e 100644
--- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonComponent.java
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonComponent.java
@@ -86,5 +86,4 @@ public abstract class HttpCommonComponent extends HeaderFilterStrategyComponent
public void setAllowJavaSerializedObject(boolean allowJavaSerializedObject) {
this.allowJavaSerializedObject = allowJavaSerializedObject;
}
-
}
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
index c6679bf..9007322 100644
--- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
@@ -16,16 +16,12 @@
*/
package org.apache.camel.http.common;
+import org.apache.camel.impl.DefaultEndpoint;
+import org.apache.camel.spi.*;
+
import java.net.URI;
import java.net.URISyntaxException;
-import org.apache.camel.impl.DefaultEndpoint;
-import org.apache.camel.spi.HeaderFilterStrategy;
-import org.apache.camel.spi.HeaderFilterStrategyAware;
-import org.apache.camel.spi.Metadata;
-import org.apache.camel.spi.UriParam;
-import org.apache.camel.spi.UriPath;
-
public abstract class HttpCommonEndpoint extends DefaultEndpoint implements HeaderFilterStrategyAware {
// Note: all options must be documented with description in annotations so extended components can access the documentation
@@ -124,6 +120,9 @@ public abstract class HttpCommonEndpoint extends DefaultEndpoint implements Head
description = "Refers to a custom org.apache.camel.component.http.UrlRewrite which allows you to rewrite urls when you bridge/proxy endpoints."
+ " See more details at http://camel.apache.org/urlrewrite.html")
private UrlRewrite urlRewrite;
+ @UriParam(label = "consumer", defaultValue = "false",
+ description = "Configure the consumer to work in async mode")
+ private boolean async;
public HttpCommonEndpoint() {
}
@@ -506,9 +505,21 @@ public abstract class HttpCommonEndpoint extends DefaultEndpoint implements Head
}
/**
- * If this option is true then IN exchange Form Encoded body will be mapped to HTTP
+ * If this option is true then IN exchange Form Encoded body will be mapped to HTTP
*/
public void setMapHttpMessageFormUrlEncodedBody(boolean mapHttpMessageFormUrlEncodedBody) {
this.mapHttpMessageFormUrlEncodedBody = mapHttpMessageFormUrlEncodedBody;
}
+
+ public boolean isAsync() {
+ return async;
+ }
+
+ /**
+ * If this option is true, the consumer will work in async mode
+ * @param async
+ */
+ public void setAsync(boolean async) {
+ this.async = async;
+ }
}
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-http/src/main/docs/http.adoc
----------------------------------------------------------------------
diff --git a/components/camel-http/src/main/docs/http.adoc b/components/camel-http/src/main/docs/http.adoc
index 677037e..24e1d4c 100644
--- a/components/camel-http/src/main/docs/http.adoc
+++ b/components/camel-http/src/main/docs/http.adoc
@@ -137,6 +137,7 @@ The HTTP component supports 6 options which are listed below.
+
// endpoint options: START
The HTTP component supports 25 endpoint options which are listed below:
@@ -173,6 +174,7 @@ The HTTP component supports 25 endpoint options which are listed below:
+
[[HTTP-MessageHeaders]]
Message Headers
^^^^^^^^^^^^^^^
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java
index 9e77b29..d9abfe2 100644
--- a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java
+++ b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java
@@ -16,29 +16,24 @@
*/
package org.apache.camel.component.jetty;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
import org.apache.camel.AsyncCallback;
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
-import org.apache.camel.http.common.CamelServlet;
-import org.apache.camel.http.common.HttpCommonEndpoint;
-import org.apache.camel.http.common.HttpConstants;
-import org.apache.camel.http.common.HttpConsumer;
-import org.apache.camel.http.common.HttpHelper;
-import org.apache.camel.http.common.HttpMessage;
+import org.apache.camel.http.common.*;
import org.apache.camel.impl.DefaultExchange;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.UnsafeUriCharactersEncoder;
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationSupport;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
/**
* Servlet which leverage <a href="http://wiki.eclipse.org/Jetty/Feature/Continuations">Jetty Continuations</a>.
*
@@ -56,7 +51,7 @@ public class CamelContinuationServlet extends CamelServlet {
private final Map<String, String> expiredExchanges = new ConcurrentHashMap<String, String>();
@Override
- protected void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
+ protected void doService(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
log.trace("Service: {}", request);
// is there a consumer registered for the request.
@@ -89,7 +84,7 @@ public class CamelContinuationServlet extends CamelServlet {
log.trace("Start request with continuation timeout of {}", continuationTimeout != null ? continuationTimeout : "jetty default");
} else {
log.trace("Usage of continuation is disabled, either by component or endpoint configuration, fallback to normal servlet processing instead");
- super.service(request, response);
+ super.doService(request, response);
return;
}
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
index b826e0d..828514b 100644
--- a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
+++ b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
@@ -16,61 +16,16 @@
*/
package org.apache.camel.component.jetty;
-import java.io.File;
-import java.io.IOException;
-import java.io.Writer;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.GeneralSecurityException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import javax.management.MBeanServer;
-import javax.servlet.Filter;
-import javax.servlet.RequestDispatcher;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.Consumer;
-import org.apache.camel.Endpoint;
-import org.apache.camel.Processor;
-import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.http.common.CamelServlet;
-import org.apache.camel.http.common.HttpBinding;
-import org.apache.camel.http.common.HttpCommonComponent;
-import org.apache.camel.http.common.HttpCommonEndpoint;
-import org.apache.camel.http.common.HttpConfiguration;
-import org.apache.camel.http.common.HttpConsumer;
-import org.apache.camel.http.common.HttpRestServletResolveConsumerStrategy;
-import org.apache.camel.http.common.UrlRewrite;
-import org.apache.camel.spi.HeaderFilterStrategy;
-import org.apache.camel.spi.ManagementAgent;
-import org.apache.camel.spi.ManagementStrategy;
-import org.apache.camel.spi.Metadata;
-import org.apache.camel.spi.RestApiConsumerFactory;
-import org.apache.camel.spi.RestConfiguration;
-import org.apache.camel.spi.RestConsumerFactory;
-import org.apache.camel.util.FileUtil;
-import org.apache.camel.util.HostUtils;
-import org.apache.camel.util.IntrospectionSupport;
-import org.apache.camel.util.ObjectHelper;
-import org.apache.camel.util.URISupport;
-import org.apache.camel.util.UnsafeUriCharactersEncoder;
+import org.apache.camel.*;
+import org.apache.camel.http.common.*;
+import org.apache.camel.spi.*;
+import org.apache.camel.util.*;
import org.apache.camel.util.jsse.SSLContextParameters;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.jmx.MBeanContainer;
-import org.eclipse.jetty.server.AbstractConnector;
-import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.*;
import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Response;
-import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
@@ -88,6 +43,21 @@ import org.eclipse.jetty.util.thread.ThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.management.MBeanServer;
+import javax.servlet.Filter;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.GeneralSecurityException;
+import java.util.*;
+
/**
* An HttpComponent which starts an embedded Jetty for to handle consuming from
* the http endpoints.
@@ -182,6 +152,7 @@ public abstract class JettyHttpComponent extends HttpCommonComponent implements
Integer httpClientMinThreads = getAndRemoveParameter(parameters, "httpClientMinThreads", Integer.class, this.httpClientMinThreads);
Integer httpClientMaxThreads = getAndRemoveParameter(parameters, "httpClientMaxThreads", Integer.class, this.httpClientMaxThreads);
HttpClient httpClient = resolveAndRemoveReferenceParameter(parameters, "httpClient", HttpClient.class);
+ Optional<Boolean> async = Optional.ofNullable(getAndRemoveParameter(parameters, "async", Boolean.class));
// extract httpClient. parameters
Map<String, Object> httpClientParameters = IntrospectionSupport.extractProperties(parameters, "httpClient.");
@@ -203,6 +174,7 @@ public abstract class JettyHttpComponent extends HttpCommonComponent implements
endpointUri = new URI(scheme + ":" + endpointUri);
JettyHttpEndpoint endpoint = createEndpoint(endpointUri, httpUri);
+ async.ifPresent(endpoint::setAsync);
if (headerFilterStrategy != null) {
endpoint.setHeaderFilterStrategy(headerFilterStrategy);
@@ -1122,6 +1094,8 @@ public abstract class JettyHttpComponent extends HttpCommonComponent implements
CamelServlet camelServlet = new CamelContinuationServlet();
ServletHolder holder = new ServletHolder();
holder.setServlet(camelServlet);
+ holder.setAsyncSupported(true);
+ holder.setInitParameter(CamelServlet.ASYNC_PARAM, Boolean.toString(endpoint.isAsync()));
context.addServlet(holder, "/*");
// use rest enabled resolver in case we use rest
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/ExplicitJettyAsyncRouteTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/ExplicitJettyAsyncRouteTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/ExplicitJettyAsyncRouteTest.java
new file mode 100644
index 0000000..63fba47
--- /dev/null
+++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/ExplicitJettyAsyncRouteTest.java
@@ -0,0 +1,66 @@
+/**
+ * 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.jetty;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Test;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Unit test for wiki demonstration.
+ */
+public class ExplicitJettyAsyncRouteTest extends BaseJettyTest {
+
+ @Test
+ public void testSendToJetty() throws Exception {
+ Object response = template.requestBody("http://localhost:{{port}}/myapp/myservice", "bookid=123");
+ // convert the response to a String
+ String body = context.getTypeConverter().convertTo(String.class, response);
+ assertEquals("<html><body>Book 123 is Camel in Action</body></html>", body);
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ public void configure() throws Exception {
+ //async and continuation is not compatible!
+ from("jetty:http://localhost:{{port}}/myapp/myservice?async=true&useContinuation=false").process(new MyBookService());
+ }
+ };
+ }
+
+ public class MyBookService implements Processor {
+ public void process(Exchange exchange) throws Exception {
+ // just get the body as a string
+ String body = exchange.getIn().getBody(String.class);
+
+ // we have access to the HttpServletRequest here and we can grab it if we need it
+ HttpServletRequest req = exchange.getIn().getBody(HttpServletRequest.class);
+ assertNotNull(req);
+
+ // for unit testing
+ assertEquals("bookid=123", body);
+
+ // send a html response
+ exchange.getOut().setBody("<html><body>Book 123 is Camel in Action</body></html>");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeAsyncRouteTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeAsyncRouteTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeAsyncRouteTest.java
new file mode 100644
index 0000000..4bd24cb
--- /dev/null
+++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeAsyncRouteTest.java
@@ -0,0 +1,48 @@
+/**
+ * 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.jetty;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+
+public class HttpBridgeAsyncRouteTest extends HttpBridgeRouteTest {
+
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ public void configure() {
+ port1 = getPort();
+ port2 = getNextPort();
+
+ errorHandler(noErrorHandler());
+
+ Processor serviceProc = new Processor() {
+ public void process(Exchange exchange) throws Exception {
+ // get the request URL and copy it to the request body
+ String uri = exchange.getIn().getHeader(Exchange.HTTP_URI, String.class);
+ exchange.getOut().setBody(uri);
+ }
+ };
+ from("jetty:http://localhost:" + port2 + "/test/hello?async=true&useContinuation=false")
+ .to("http://localhost:" + port1 + "?throwExceptionOnFailure=false&bridgeEndpoint=true");
+
+ from("jetty://http://localhost:" + port1 + "?matchOnUriPrefix=true&async=true&useContinuation=false").process(serviceProc);
+ }
+ };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeRouteTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeRouteTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeRouteTest.java
index 5303e6a..edfbd3a 100644
--- a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeRouteTest.java
+++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpBridgeRouteTest.java
@@ -16,18 +16,18 @@
*/
package org.apache.camel.component.jetty;
-import java.io.ByteArrayInputStream;
-
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.builder.RouteBuilder;
import org.junit.Test;
+import java.io.ByteArrayInputStream;
+
public class HttpBridgeRouteTest extends BaseJettyTest {
- private int port1;
- private int port2;
+ protected int port1;
+ protected int port2;
@Test
public void testHttpClient() throws Exception {
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsAsyncRouteTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsAsyncRouteTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsAsyncRouteTest.java
new file mode 100644
index 0000000..6e3041b
--- /dev/null
+++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsAsyncRouteTest.java
@@ -0,0 +1,196 @@
+/**
+ * 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.jetty;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.SocketException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+
+public class HttpsAsyncRouteTest extends HttpsRouteTest {
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ port1 = getNextPort();
+ port2 = getNextPort(port1 + 1);
+
+ super.setUp();
+ // ensure jsse clients can validate the self signed dummy localhost cert,
+ // use the server keystore as the trust store for these tests
+ URL trustStoreUrl = this.getClass().getClassLoader().getResource("jsse/localhost.ks");
+ setSystemProp("javax.net.ssl.trustStore", trustStoreUrl.toURI().getPath());
+ }
+
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ restoreSystemProperties();
+ super.tearDown();
+ }
+
+ protected void setSystemProp(String key, String value) {
+ String originalValue = System.setProperty(key, value);
+ originalValues.put(key, originalValue != null ? originalValue : NULL_VALUE_MARKER);
+ }
+
+ protected void restoreSystemProperties() {
+ for (Object key : originalValues.keySet()) {
+ Object value = originalValues.get(key);
+ if (NULL_VALUE_MARKER.equals(value)) {
+ System.getProperties().remove(key);
+ } else {
+ System.setProperty((String)key, (String)value);
+ }
+ }
+ }
+
+ @Test
+ public void testEndpoint() throws Exception {
+ // these tests does not run well on Windows
+ if (isPlatform("windows")) {
+ return;
+ }
+
+ MockEndpoint mockEndpointA = resolveMandatoryEndpoint("mock:a", MockEndpoint.class);
+ mockEndpointA.expectedBodiesReceived(expectedBody);
+ MockEndpoint mockEndpointB = resolveMandatoryEndpoint("mock:b", MockEndpoint.class);
+ mockEndpointB.expectedBodiesReceived(expectedBody);
+
+ invokeHttpEndpoint();
+
+ mockEndpointA.assertIsSatisfied();
+ mockEndpointB.assertIsSatisfied();
+ List<Exchange> list = mockEndpointA.getReceivedExchanges();
+ Exchange exchange = list.get(0);
+ assertNotNull("exchange", exchange);
+
+ Message in = exchange.getIn();
+ assertNotNull("in", in);
+
+ Map<String, Object> headers = in.getHeaders();
+
+ log.info("Headers: " + headers);
+
+ assertTrue("Should be more than one header but was: " + headers, headers.size() > 0);
+ }
+
+ @Test
+ public void testEndpointWithoutHttps() throws Exception {
+ // these tests does not run well on Windows
+ if (isPlatform("windows")) {
+ return;
+ }
+
+ MockEndpoint mockEndpoint = resolveMandatoryEndpoint("mock:a", MockEndpoint.class);
+ try {
+ template.sendBodyAndHeader("http://localhost:" + port1 + "/test", expectedBody, "Content-Type", "application/xml");
+ fail("expect exception on access to https endpoint via http");
+ } catch (RuntimeCamelException expected) {
+ }
+ assertTrue("mock endpoint was not called", mockEndpoint.getExchanges().isEmpty());
+ }
+
+ @Test
+ public void testHelloEndpoint() throws Exception {
+ // these tests does not run well on Windows
+ if (isPlatform("windows")) {
+ return;
+ }
+
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ InputStream is = new URL("https://localhost:" + port1 + "/hello").openStream();
+ int c;
+ while ((c = is.read()) >= 0) {
+ os.write(c);
+ }
+
+ String data = new String(os.toByteArray());
+ assertEquals("<b>Hello World</b>", data);
+ }
+
+ @Test
+ public void testHelloEndpointWithoutHttps() throws Exception {
+ // these tests does not run well on Windows
+ if (isPlatform("windows")) {
+ return;
+ }
+
+ try {
+ new URL("http://localhost:" + port1 + "/hello").openStream();
+ fail("expected SocketException on use ot http");
+ } catch (SocketException expected) {
+ }
+ }
+
+ protected void invokeHttpEndpoint() throws IOException {
+ template.sendBodyAndHeader(getHttpProducerScheme() + "localhost:" + port1 + "/test", expectedBody, "Content-Type", "application/xml");
+ template.sendBodyAndHeader(getHttpProducerScheme() + "localhost:" + port2 + "/test", expectedBody, "Content-Type", "application/xml");
+ }
+
+ protected void configureSslContextFactory(SslContextFactory sslContextFactory) {
+ sslContextFactory.setKeyManagerPassword(pwd);
+ sslContextFactory.setKeyStorePassword(pwd);
+ URL keyStoreUrl = this.getClass().getClassLoader().getResource("jsse/localhost.ks");
+ try {
+ sslContextFactory.setKeyStorePath(keyStoreUrl.toURI().getPath());
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ sslContextFactory.setTrustStoreType("JKS");
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ public void configure() throws URISyntaxException {
+ JettyHttpComponent componentJetty = (JettyHttpComponent) context.getComponent("jetty");
+ componentJetty.setSslPassword(pwd);
+ componentJetty.setSslKeyPassword(pwd);
+ URL keyStoreUrl = this.getClass().getClassLoader().getResource("jsse/localhost.ks");
+ componentJetty.setKeystore(keyStoreUrl.toURI().getPath());
+
+ from("jetty:https://localhost:" + port1 + "/test?async=true&useContinuation=false").to("mock:a");
+
+ Processor proc = new Processor() {
+ public void process(Exchange exchange) throws Exception {
+ exchange.getOut().setBody("<b>Hello World</b>");
+ }
+ };
+ from("jetty:https://localhost:" + port1 + "/hello?async=true&useContinuation=false").process(proc);
+
+ from("jetty:https://localhost:" + port2 + "/test?async=true&useContinuation=false").to("mock:b");
+ }
+ };
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsRouteTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsRouteTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsRouteTest.java
index 56cf84b..9a3e04b 100644
--- a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsRouteTest.java
+++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/HttpsRouteTest.java
@@ -16,16 +16,6 @@
*/
package org.apache.camel.component.jetty;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.SocketException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;
@@ -38,9 +28,19 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.SocketException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
public class HttpsRouteTest extends BaseJettyTest {
- private static final String NULL_VALUE_MARKER = CamelTestSupport.class.getCanonicalName();
+ public static final String NULL_VALUE_MARKER = CamelTestSupport.class.getCanonicalName();
protected String expectedBody = "<hello>world!</hello>";
protected String pwd = "changeit";
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-servlet/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-servlet/pom.xml b/components/camel-servlet/pom.xml
index f1f84f1..56c1050 100644
--- a/components/camel-servlet/pom.xml
+++ b/components/camel-servlet/pom.xml
@@ -30,6 +30,7 @@
<description>Camel servlet transport support</description>
<properties>
+ <tomcat.version>8.5.0</tomcat.version>
<camel.osgi.import.before.defaults>
javax.servlet.*;version="${servlet-version-range}"
</camel.osgi.import.before.defaults>
@@ -37,6 +38,18 @@
<camel.osgi.export.service>org.apache.camel.spi.ComponentResolver;component=servlet</camel.osgi.export.service>
</properties>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.arquillian</groupId>
+ <artifactId>arquillian-bom</artifactId>
+ <version>${arquillian-version}</version>
+ <scope>import</scope>
+ <type>pom</type>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
<dependencies>
<dependency>
@@ -113,6 +126,69 @@
<artifactId>camel-jaxb</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>com.jayway.restassured</groupId>
+ <artifactId>rest-assured</artifactId>
+ <version>${rest-assured-version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.junit</groupId>
+ <artifactId>arquillian-junit-container</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <!--jetty-->
+ <!--https://github.com/GoogleCloudPlatform/appengine-java-vm-runtime/issues/23-->
+ <!--Still not fixed in 9.3.8.v20160314 and 9.3.9.M1, produce 404 NOT FOUND or a 500 if we remove the async-supported flag :-(-->
+ <!--<dependency>
+ <groupId>org.jboss.arquillian.container</groupId>
+ <artifactId>arquillian-jetty-embedded-9</artifactId>
+ <version>1.0.0.CR3</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-webapp</artifactId>
+ <version>${jetty9-version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-deploy</artifactId>
+ <version>${jetty9-version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-annotations</artifactId>
+ <version>${jetty9-version}</version>
+ <scope>runtime</scope>
+ </dependency>-->
+ <!--tomcat-->
+ <dependency>
+ <groupId>org.jboss.arquillian.container</groupId>
+ <artifactId>arquillian-tomcat-embedded-8</artifactId>
+ <version>1.0.0.CR7</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat.embed</groupId>
+ <artifactId>tomcat-embed-core</artifactId>
+ <version>${tomcat.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat.embed</groupId>
+ <artifactId>tomcat-embed-jasper</artifactId>
+ <version>${tomcat.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat.embed</groupId>
+ <artifactId>tomcat-embed-logging-juli</artifactId>
+ <version>${tomcat.version}</version>
+ <scope>runtime</scope>
+ </dependency>
</dependencies>
<build>
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java
index 34f5039..2a16ebf 100644
--- a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java
+++ b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java
@@ -16,11 +16,6 @@
*/
package org.apache.camel.component.servlet;
-import java.net.URI;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
import org.apache.camel.CamelContext;
import org.apache.camel.Consumer;
import org.apache.camel.Endpoint;
@@ -37,6 +32,12 @@ import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.URISupport;
import org.apache.camel.util.UnsafeUriCharactersEncoder;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Optional;
+
public class ServletComponent extends HttpCommonComponent implements RestConsumerFactory, RestApiConsumerFactory {
private String servletName = "CamelServlet";
@@ -61,6 +62,7 @@ public class ServletComponent extends HttpCommonComponent implements RestConsume
String servletName = getAndRemoveParameter(parameters, "servletName", String.class, getServletName());
String httpMethodRestrict = getAndRemoveParameter(parameters, "httpMethodRestrict", String.class);
HeaderFilterStrategy headerFilterStrategy = resolveAndRemoveReferenceParameter(parameters, "headerFilterStrategy", HeaderFilterStrategy.class);
+ Optional<Boolean> async = Optional.ofNullable(getAndRemoveParameter(parameters, "async", Boolean.class));
if (lenientContextPath()) {
// the uri must have a leading slash for the context-path matching to work with servlet, and it can be something people
@@ -80,6 +82,7 @@ public class ServletComponent extends HttpCommonComponent implements RestConsume
ServletEndpoint endpoint = createServletEndpoint(uri, this, httpUri);
endpoint.setServletName(servletName);
+ async.ifPresent(endpoint::setAsync);
if (headerFilterStrategy != null) {
endpoint.setHeaderFilterStrategy(headerFilterStrategy);
} else {
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletEndpoint.java b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletEndpoint.java
index 5beefc3..a22ffdb 100644
--- a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletEndpoint.java
+++ b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletEndpoint.java
@@ -16,9 +16,6 @@
*/
package org.apache.camel.component.servlet;
-import java.net.URI;
-import java.net.URISyntaxException;
-
import org.apache.camel.Consumer;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
@@ -28,6 +25,9 @@ import org.apache.camel.spi.UriEndpoint;
import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriPath;
+import java.net.URI;
+import java.net.URISyntaxException;
+
/**
* To use a HTTP Servlet as entry for Camel routes when running in a servlet container.
*/
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletAsyncArquillianTest.java
----------------------------------------------------------------------
diff --git a/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletAsyncArquillianTest.java b/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletAsyncArquillianTest.java
new file mode 100644
index 0000000..8ce0d98
--- /dev/null
+++ b/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletAsyncArquillianTest.java
@@ -0,0 +1,52 @@
+package org.apache.camel.component.servlet;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.RunAsClient;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.URL;
+import java.nio.file.Paths;
+import java.text.MessageFormat;
+
+import static com.jayway.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.equalTo;
+
+/**
+ * @author arnaud.deprez
+ * @since 18/04/16
+ */
+@RunWith(Arquillian.class)
+public class ServletAsyncArquillianTest {
+
+ @Deployment
+ public static Archive<?> createTestArchive() {
+ // this is a WAR project so use WebArchive
+ return ShrinkWrap.create(WebArchive.class)
+ // add the web.xml
+ .setWebXML(Paths.get("src/test/resources/org/apache/camel/component/servlet/web-spring-async.xml").toFile());
+ }
+
+ /**
+ *
+ * @param url the URL is the URL to the web application that was deployed
+ * @throws Exception
+ */
+ @Test
+ @RunAsClient
+ public void testHello(@ArquillianResource URL url) throws Exception {
+ final String name = "Arnaud";
+ given().
+ baseUri(url.toString()).
+ queryParam("name", name).
+ when().
+ get("/services/hello").
+ then().
+ body(equalTo(MessageFormat.format("Hello {0} how are you?", name)));
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/6a1f84e0/components/camel-servlet/src/test/resources/org/apache/camel/component/servlet/web-spring-async.xml
----------------------------------------------------------------------
diff --git a/components/camel-servlet/src/test/resources/org/apache/camel/component/servlet/web-spring-async.xml b/components/camel-servlet/src/test/resources/org/apache/camel/component/servlet/web-spring-async.xml
new file mode 100644
index 0000000..8e9accd
--- /dev/null
+++ b/components/camel-servlet/src/test/resources/org/apache/camel/component/servlet/web-spring-async.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!DOCTYPE web-app
+ PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<!--
+ 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.
+-->
+<!-- START SNIPPET: web -->
+<web-app>
+ <!-- tell Spring where it should load the XML file -->
+ <context-param>
+ <param-name>contextConfigLocation</param-name>
+ <param-value>classpath:org/apache/camel/component/servlet/example-camelContext.xml</param-value>
+ </context-param>
+
+ <!-- spring context listener which loads the XML file -->
+ <listener>
+ <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+ </listener>
+
+ <servlet>
+ <servlet-name>CamelServlet</servlet-name>
+ <display-name>Camel Http Transport Servlet</display-name>
+ <servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet</servlet-class>
+ <init-param>
+ <param-name>async</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ <async-supported>true</async-supported>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>CamelServlet</servlet-name>
+ <url-pattern>/services/*</url-pattern>
+ </servlet-mapping>
+
+</web-app>
+<!-- END SNIPPET: web -->
\ No newline at end of file