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 2010/12/29 17:21:06 UTC

svn commit: r1053667 - in /camel/trunk/components: camel-http/src/main/java/org/apache/camel/component/http/ camel-http/src/main/java/org/apache/camel/component/http/helper/ camel-http/src/test/java/org/apache/camel/component/http/helper/ camel-jetty/s...

Author: davsclaus
Date: Wed Dec 29 16:21:05 2010
New Revision: 1053667

URL: http://svn.apache.org/viewvc?rev=1053667&view=rev
Log:
CAMEL-3218: http/jetty/servlet now supports content type with serialized java objects both on producer and consumer side. Added some missing options in camel-servlet.

Added:
    camel/trunk/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpHelperTest.java   (contents, props changed)
      - copied, changed from r1053350, camel/trunk/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpProducerHelperTest.java
    camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/javabody/
    camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/javabody/HttpJavaBodyTest.java
    camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/javabody/MyCoolBean.java
    camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerJavaBodyTest.java
    camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerTransferExceptionTest.java
    camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/MyCoolBean.java
    camel/trunk/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletTransferExceptionTest.java
Removed:
    camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/HttpProducerHelper.java
    camel/trunk/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpProducerHelperTest.java
Modified:
    camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java
    camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java
    camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/CamelFileDataSource.java
    camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/GZIPHelper.java
    camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/HttpHelper.java
    camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/DefaultJettyHttpBinding.java
    camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyContentExchange.java
    camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpBinding.java
    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
    camel/trunk/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java

Modified: camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java?rev=1053667&r1=1053666&r2=1053667&view=diff
==============================================================================
--- camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java (original)
+++ camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java Wed Dec 29 16:21:05 2010
@@ -20,6 +20,7 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
+import java.io.Serializable;
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.util.Enumeration;
@@ -106,7 +107,7 @@ public class DefaultHttpBinding implemen
         if (body instanceof StreamCache) {
             ((StreamCache)body).reset();
         }
-        
+
         // store the method and query and other info in headers
         headers.put(Exchange.HTTP_METHOD, request.getMethod());
         headers.put(Exchange.HTTP_QUERY, request.getQueryString());
@@ -114,6 +115,19 @@ public class DefaultHttpBinding implemen
         headers.put(Exchange.HTTP_URI, request.getRequestURI());
         headers.put(Exchange.HTTP_PATH, request.getPathInfo());
         headers.put(Exchange.CONTENT_TYPE, request.getContentType());
+
+        // if content type is serialized java object, then de-serialize it to a Java object
+        if (request.getContentType() != null && HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(request.getContentType())) {
+            try {
+                InputStream is = endpoint.getCamelContext().getTypeConverter().mandatoryConvertTo(InputStream.class, body);
+                Object object = HttpHelper.deserializeJavaObjectFromStream(is);
+                if (object != null) {
+                    message.setBody(object);
+                }
+            } catch (Exception e) {
+                throw new RuntimeCamelException("Cannot deserialize body to Java object", e);
+            }
+        }
         
         populateAttachments(request, message);
     }
@@ -246,6 +260,20 @@ public class DefaultHttpBinding implemen
     }
 
     protected void doWriteDirectResponse(Message message, HttpServletResponse response, Exchange exchange) throws IOException {
+        // if content type is serialized Java object, then serialize and write it to the response
+        String contentType = message.getHeader(Exchange.CONTENT_TYPE, String.class);
+        if (contentType != null && HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType)) {
+            try {
+                Object object = message.getMandatoryBody(Serializable.class);
+                HttpHelper.writeObjectToServletResponse(response, object);
+                // object is written so return
+                return;
+            } catch (InvalidPayloadException e) {
+                throw IOHelper.createIOException(e);
+            }
+        }
+
+        // other kind of content type
         InputStream is = null;
         if (checkChunked(message, exchange)) {
             is = message.getBody(InputStream.class);

Modified: camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java?rev=1053667&r1=1053666&r2=1053667&view=diff
==============================================================================
--- camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java (original)
+++ camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java Wed Dec 29 16:21:05 2010
@@ -16,22 +16,23 @@
  */
 package org.apache.camel.component.http;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
 import java.io.UnsupportedEncodingException;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.camel.CamelExchangeException;
 import org.apache.camel.Exchange;
-import org.apache.camel.InvalidPayloadException;
 import org.apache.camel.Message;
-import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.component.file.GenericFile;
 import org.apache.camel.component.http.helper.GZIPHelper;
 import org.apache.camel.component.http.helper.HttpHelper;
-import org.apache.camel.component.http.helper.HttpProducerHelper;
 import org.apache.camel.converter.IOConverter;
 import org.apache.camel.converter.stream.CachedOutputStream;
 import org.apache.camel.impl.DefaultProducer;
@@ -42,6 +43,7 @@ import org.apache.commons.httpclient.Hea
 import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.HttpMethod;
 import org.apache.commons.httpclient.HttpVersion;
+import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
 import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
 import org.apache.commons.httpclient.methods.FileRequestEntity;
 import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
@@ -68,10 +70,10 @@ public class HttpProducer extends Defaul
     }
 
     public void process(Exchange exchange) throws Exception {
-        if (((HttpEndpoint)getEndpoint()).isBridgeEndpoint()) {
+        if (getEndpoint().isBridgeEndpoint()) {
             exchange.setProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.TRUE);
         }
-        HttpMethod method = createMethod(exchange);        
+        HttpMethod method = createMethod(exchange);
         Message in = exchange.getIn();
         String httpProtocolVersion = in.getHeader(Exchange.HTTP_PROTOCOL_VERSION, String.class);
         if (httpProtocolVersion != null) {
@@ -79,7 +81,7 @@ public class HttpProducer extends Defaul
             HttpMethodParams params = method.getParams();
             params.setVersion(HttpVersion.parse(httpProtocolVersion));
         }
-        
+
         HeaderFilterStrategy strategy = getEndpoint().getHeaderFilterStrategy();
 
         // propagate headers as HTTP headers
@@ -183,7 +185,7 @@ public class HttpProducer extends Defaul
     /**
      * Strategy when executing the method (calling the remote server).
      *
-     * @param method    the method to execute
+     * @param method the method to execute
      * @return the response code
      * @throws IOException can be thrown
      */
@@ -213,8 +215,8 @@ public class HttpProducer extends Defaul
     /**
      * Extracts the response from the method as a InputStream.
      *
-     * @param method  the method that was executed
-     * @return  the response either as a stream, or as a deserialized java object
+     * @param method the method that was executed
+     * @return the response either as a stream, or as a deserialized java object
      * @throws IOException can be thrown
      */
     protected static Object extractResponseBody(HttpMethod method, Exchange exchange) throws IOException, ClassNotFoundException {
@@ -223,13 +225,13 @@ public class HttpProducer extends Defaul
             return null;
         }
 
-        Header header = method.getResponseHeader(Exchange.CONTENT_ENCODING);        
+        Header header = method.getResponseHeader(Exchange.CONTENT_ENCODING);
         String contentEncoding = header != null ? header.getValue() : null;
-        
+
         if (!exchange.getProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.FALSE, Boolean.class)) {
             is = GZIPHelper.uncompressGzip(contentEncoding, is);
         }
-        
+
         // Honor the character encoding
         String contentType = null;
         header = method.getResponseHeader("content-type");
@@ -239,30 +241,14 @@ public class HttpProducer extends Defaul
             HttpHelper.setCharsetFromContentType(contentType, exchange);
         }
         InputStream response = doExtractResponseBodyAsStream(is, exchange);
+        // if content type is a serialized java object then de-serialize it back to a Java object
         if (contentType != null && contentType.equals(HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT)) {
-            return doDeserializeJavaObjectFromResponse(response);
+            return HttpHelper.deserializeJavaObjectFromStream(response);
         } else {
             return response;
         }
     }
 
-    private static Object doDeserializeJavaObjectFromResponse(InputStream response) throws ClassNotFoundException, IOException {
-        if (response == null) {
-            LOG.debug("Cannot deserialize response body as java object as there are no response body.");
-            return null;
-        }
-
-        Object answer = null;
-        ObjectInputStream ois = new ObjectInputStream(response);
-        try {
-            answer = ois.readObject();
-        } finally {
-            IOHelper.close(ois);
-        }
-
-        return answer;
-    }
-
     private static InputStream doExtractResponseBodyAsStream(InputStream is, Exchange exchange) throws IOException {
         // As httpclient is using a AutoCloseInputStream, it will be closed when the connection is closed
         // we need to cache the stream for it.
@@ -273,30 +259,29 @@ public class HttpProducer extends Defaul
             // When the InputStream is closed, the CachedOutputStream will be closed
             return cos.getWrappedInputStream();
         } finally {
-            IOHelper.close(is, "Extracting response body", LOG);            
+            IOHelper.close(is, "Extracting response body", LOG);
         }
     }
 
     /**
      * Creates the HttpMethod to use to call the remote server, either its GET or POST.
      *
-     * @param exchange  the exchange
+     * @param exchange the exchange
      * @return the created method as either GET or POST
-     * @throws org.apache.camel.InvalidPayloadException is thrown if message body cannot
-     * be converted to a type supported by HttpClient
+     * @throws CamelExchangeException is thrown if error creating RequestEntity
      */
-    protected HttpMethod createMethod(Exchange exchange) throws InvalidPayloadException {
+    protected HttpMethod createMethod(Exchange exchange) throws CamelExchangeException {
 
-        String url = HttpProducerHelper.createURL(exchange, getEndpoint());
+        String url = HttpHelper.createURL(exchange, getEndpoint());
 
         RequestEntity requestEntity = createRequestEntity(exchange);
-        HttpMethods methodToUse = HttpProducerHelper.createMethod(exchange, getEndpoint(), requestEntity != null);
+        HttpMethods methodToUse = HttpHelper.createMethod(exchange, getEndpoint(), requestEntity != null);
         HttpMethod method = methodToUse.createMethod(url);
 
         // is a query string provided in the endpoint URI or in a header (header overrules endpoint)
         String queryString = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
         if (queryString == null) {
-            queryString = getEndpoint().getHttpUri().getRawQuery();            
+            queryString = getEndpoint().getHttpUri().getRawQuery();
         }
         if (queryString != null) {
             // need to make sure the queryString is URI safe
@@ -304,7 +289,7 @@ public class HttpProducer extends Defaul
         }
 
         if (methodToUse.isEntityEnclosing()) {
-            ((EntityEnclosingMethod)method).setRequestEntity(requestEntity);
+            ((EntityEnclosingMethod) method).setRequestEntity(requestEntity);
             if (requestEntity != null && requestEntity.getContentType() == null) {
                 if (LOG.isDebugEnabled()) {
                     LOG.debug("No Content-Type provided for URL: " + url + " with exchange: " + exchange);
@@ -318,12 +303,11 @@ public class HttpProducer extends Defaul
     /**
      * Creates a holder object for the data to send to the remote server.
      *
-     * @param exchange  the exchange with the IN message with data to send
+     * @param exchange the exchange with the IN message with data to send
      * @return the data holder
-     * @throws org.apache.camel.InvalidPayloadException is thrown if message body cannot
-     * be converted to a type supported by HttpClient
+     * @throws CamelExchangeException is thrown if error creating RequestEntity
      */
-    protected RequestEntity createRequestEntity(Exchange exchange) throws InvalidPayloadException {
+    protected RequestEntity createRequestEntity(Exchange exchange) throws CamelExchangeException {
         Message in = exchange.getIn();
         if (in.getBody() == null) {
             return null;
@@ -336,8 +320,16 @@ public class HttpProducer extends Defaul
                 if (data != null) {
                     String contentType = ExchangeHelper.getContentType(exchange);
 
-                    // file based (could potentially also be a FTP file etc)
-                    if (data instanceof File || data instanceof GenericFile) {
+                    if (contentType != null && HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType)) {
+                        // serialized java object
+                        Serializable obj = in.getMandatoryBody(Serializable.class);
+                        // write object to output stream
+                        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                        HttpHelper.writeObjectToStream(bos, obj);
+                        answer = new ByteArrayRequestEntity(bos.toByteArray(), HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT);
+                        IOHelper.close(bos);
+                    } else if (data instanceof File || data instanceof GenericFile) {
+                        // file based (could potentially also be a FTP file etc)
                         File file = in.getBody(File.class);
                         if (file != null) {
                             answer = new FileRequestEntity(file, contentType);
@@ -348,7 +340,7 @@ public class HttpProducer extends Defaul
                         // do not fallback to use the default charset as it can influence the request
                         // (for example application/x-www-form-urlencoded forms being sent)
                         String charset = IOConverter.getCharsetName(exchange, false);
-                        answer = new StringRequestEntity((String)data, contentType, charset);
+                        answer = new StringRequestEntity((String) data, contentType, charset);
                     }
                     // fallback as input stream
                     if (answer == null) {
@@ -358,7 +350,9 @@ public class HttpProducer extends Defaul
                     }
                 }
             } catch (UnsupportedEncodingException e) {
-                throw new RuntimeCamelException(e);
+                throw new CamelExchangeException("Error creating RequestEntity from message body", exchange, e);
+            } catch (IOException e) {
+                throw new CamelExchangeException("Error serializing message body", exchange, e);
             }
         }
         return answer;

Modified: camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/CamelFileDataSource.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/CamelFileDataSource.java?rev=1053667&r1=1053666&r2=1053667&view=diff
==============================================================================
--- camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/CamelFileDataSource.java (original)
+++ camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/CamelFileDataSource.java Wed Dec 29 16:21:05 2010
@@ -22,7 +22,7 @@ import javax.activation.FileDataSource;
 import javax.activation.FileTypeMap;
 
 public class CamelFileDataSource extends FileDataSource {
-    private String fileName;
+    private final String fileName;
     private FileTypeMap typeMap;
 
     public CamelFileDataSource(File file, String fileName) {

Modified: camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/GZIPHelper.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/GZIPHelper.java?rev=1053667&r1=1053666&r2=1053667&view=diff
==============================================================================
--- camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/GZIPHelper.java (original)
+++ camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/GZIPHelper.java Wed Dec 29 16:21:05 2010
@@ -52,8 +52,8 @@ public final class GZIPHelper {
                 gzip.finish();
                 return new ByteArrayInputStream(os.toByteArray());
             } finally {
-                IOHelper.close(gzip, "gzip", null);
-                IOHelper.close(os, "byte array output stream", null);
+                IOHelper.close(gzip, "gzip");
+                IOHelper.close(os, "byte array output stream");
             }
         } else {
             return in;
@@ -71,8 +71,8 @@ public final class GZIPHelper {
                 gzip.finish();
                 return new ByteArrayInputStream(os.toByteArray());
             } finally {
-                IOHelper.close(gzip, "gzip", null);
-                IOHelper.close(os, "byte array", null);
+                IOHelper.close(gzip, "gzip");
+                IOHelper.close(os, "byte array output stream");
             }
         } else {
             return new ByteArrayInputStream(data);
@@ -87,8 +87,8 @@ public final class GZIPHelper {
             gzip.finish();
             return os.toByteArray();
         } finally {
-            gzip.close();
-            os.close();
+            IOHelper.close(gzip, "gzip");
+            IOHelper.close(os, "byte array");
         }
     }
 

Modified: camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/HttpHelper.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/HttpHelper.java?rev=1053667&r1=1053666&r2=1053667&view=diff
==============================================================================
--- camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/HttpHelper.java (original)
+++ camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/helper/HttpHelper.java Wed Dec 29 16:21:05 2010
@@ -18,13 +18,19 @@ package org.apache.camel.component.http.
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.net.URI;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.camel.Exchange;
+import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.component.http.HttpConstants;
 import org.apache.camel.component.http.HttpConverter;
+import org.apache.camel.component.http.HttpEndpoint;
+import org.apache.camel.component.http.HttpMethods;
 import org.apache.camel.converter.IOConverter;
 import org.apache.camel.converter.stream.CachedOutputStream;
 import org.apache.camel.util.IOHelper;
@@ -57,13 +63,48 @@ public final class HttpHelper {
      */
     public static void writeObjectToServletResponse(ServletResponse response, Object target) throws IOException {
         response.setContentType(HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT);
-        ObjectOutputStream oos = new ObjectOutputStream(response.getOutputStream());
+        writeObjectToStream(response.getOutputStream(), target);
+    }
+
+    /**
+     * Writes the given object as response body to the output stream
+     *
+     * @param stream output stream
+     * @param target   object to write
+     * @throws IOException is thrown if error writing
+     */
+    public static void writeObjectToStream(OutputStream stream, Object target) throws IOException {
+        ObjectOutputStream oos = new ObjectOutputStream(stream);
         oos.writeObject(target);
         oos.flush();
         IOHelper.close(oos);
     }
 
     /**
+     * Deserializes the input stream to a Java object
+     *
+     * @param is input stream for the Java object
+     * @return the java object, or <tt>null</tt> if input stream was <tt>null</tt>
+     * @throws ClassNotFoundException is thrown if class not found
+     * @throws IOException can be thrown
+     */
+    public static Object deserializeJavaObjectFromStream(InputStream is) throws ClassNotFoundException, IOException {
+        if (is == null) {
+            return null;
+        }
+
+        Object answer = null;
+        ObjectInputStream ois = new ObjectInputStream(is);
+        try {
+            answer = ois.readObject();
+        } finally {
+            IOHelper.close(ois);
+        }
+
+        return answer;
+    }
+
+    /**
      * Reads the response body from the given http servlet request.
      *
      * @param request  http servlet request
@@ -99,4 +140,93 @@ public final class HttpHelper {
         }
     }
 
+    /**
+     * Creates the URL to invoke.
+     *
+     * @param exchange the exchange
+     * @param endpoint the endpoint
+     * @return the URL to invoke
+     */
+    public static String createURL(Exchange exchange, HttpEndpoint endpoint) {
+        String uri = null;
+        if (!(endpoint.isBridgeEndpoint())) {
+            uri = exchange.getIn().getHeader(Exchange.HTTP_URI, String.class);
+        }
+        if (uri == null) {
+            uri = endpoint.getHttpUri().toASCIIString();
+        }
+
+        // append HTTP_PATH to HTTP_URI if it is provided in the header
+        String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class);
+        if (path != null) {
+            if (path.startsWith("/")) {
+                URI baseURI;
+                String baseURIString = exchange.getIn().getHeader(Exchange.HTTP_BASE_URI, String.class);
+                try {
+                    if (baseURIString == null) {
+                        if (exchange.getFromEndpoint() != null) {
+                            baseURIString = exchange.getFromEndpoint().getEndpointUri();
+                        } else {
+                            // will set a default one for it
+                            baseURIString = "/";
+                        }
+                    }
+                    baseURI = new URI(baseURIString);
+                    String basePath = baseURI.getRawPath();
+                    if (path.startsWith(basePath)) {
+                        path = path.substring(basePath.length());
+                        if (path.startsWith("/")) {
+                            path = path.substring(1);
+                        }
+                    } else {
+                        throw new RuntimeCamelException("Cannot analyze the Exchange.HTTP_PATH header, due to: cannot find the right HTTP_BASE_URI");
+                    }
+                } catch (Throwable t) {
+                    throw new RuntimeCamelException("Cannot analyze the Exchange.HTTP_PATH header, due to: "
+                                                    + t.getMessage(), t);
+                }
+
+            }
+            if (path.length() > 0) {
+                // make sure that there is exactly one "/" between HTTP_URI and
+                // HTTP_PATH
+                if (!uri.endsWith("/")) {
+                    uri = uri + "/";
+                }
+                uri = uri.concat(path);
+            }
+        }
+        return uri;
+    }
+
+    /**
+     * Creates the HttpMethod to use to call the remote server, often either its GET or POST.
+     *
+     * @param exchange  the exchange
+     * @return the created method
+     */
+    public static HttpMethods createMethod(Exchange exchange, HttpEndpoint endpoint, boolean hasPayload) {
+        // is a query string provided in the endpoint URI or in a header (header
+        // overrules endpoint)
+        String queryString = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
+        if (queryString == null) {
+            queryString = endpoint.getHttpUri().getQuery();
+        }
+
+        // compute what method to use either GET or POST
+        HttpMethods answer;
+        HttpMethods m = exchange.getIn().getHeader(Exchange.HTTP_METHOD, HttpMethods.class);
+        if (m != null) {
+            // always use what end-user provides in a header
+            answer = m;
+        } else if (queryString != null) {
+            // if a query string is provided then use GET
+            answer = HttpMethods.GET;
+        } else {
+            // fallback to POST if we have payload, otherwise GET
+            answer = hasPayload ? HttpMethods.POST : HttpMethods.GET;
+        }
+
+        return answer;
+    }
 }

Copied: camel/trunk/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpHelperTest.java (from r1053350, camel/trunk/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpProducerHelperTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpHelperTest.java?p2=camel/trunk/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpHelperTest.java&p1=camel/trunk/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpProducerHelperTest.java&r1=1053350&r2=1053667&rev=1053667&view=diff
==============================================================================
--- camel/trunk/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpProducerHelperTest.java (original)
+++ camel/trunk/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpHelperTest.java Wed Dec 29 16:21:05 2010
@@ -30,11 +30,11 @@ import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
 
-public class HttpProducerHelperTest {
+public class HttpHelperTest {
 
     @Test
     public void createURLShouldReturnTheHeaderURIIfNotBridgeEndpoint() throws URISyntaxException {
-        String url = HttpProducerHelper.createURL(
+        String url = HttpHelper.createURL(
                 createExchangeWithOptionalCamelHttpUriHeader("http://apache.org", null),
                 createHttpEndpoint(false, "http://camel.apache.org"));
 
@@ -43,7 +43,7 @@ public class HttpProducerHelperTest {
 
     @Test
     public void createURLShouldReturnTheEndpointURIIfBridgeEndpoint() throws URISyntaxException {
-        String url = HttpProducerHelper.createURL(
+        String url = HttpHelper.createURL(
                 createExchangeWithOptionalCamelHttpUriHeader("http://apache.org", null),
                 createHttpEndpoint(true, "http://camel.apache.org"));
 
@@ -52,7 +52,7 @@ public class HttpProducerHelperTest {
 
     @Test
     public void createURLShouldReturnTheEndpointURIIfNotBridgeEndpoint() throws URISyntaxException {
-        String url = HttpProducerHelper.createURL(
+        String url = HttpHelper.createURL(
                 createExchangeWithOptionalCamelHttpUriHeader(null, null),
                 createHttpEndpoint(false, "http://camel.apache.org"));
 
@@ -61,7 +61,7 @@ public class HttpProducerHelperTest {
 
     @Test
     public void createURLShouldReturnTheEndpointURIWithHeaderHttpPathAndAddOneSlash() throws URISyntaxException {
-        String url = HttpProducerHelper.createURL(
+        String url = HttpHelper.createURL(
                 createExchangeWithOptionalCamelHttpUriHeader(null, "search"),
                 createHttpEndpoint(true, "http://www.google.com"));
 
@@ -70,7 +70,7 @@ public class HttpProducerHelperTest {
 
     @Test
     public void createURLShouldReturnTheEndpointURIWithHeaderHttpPathAndRemoveOneSlash() throws URISyntaxException {
-        String url = HttpProducerHelper.createURL(
+        String url = HttpHelper.createURL(
                 createExchangeWithOptionalCamelHttpUriHeader(null, "/search"),
                 createHttpEndpoint(true, "http://www.google.com/"));
 
@@ -79,7 +79,7 @@ public class HttpProducerHelperTest {
 
     @Test
     public void createMethodAlwaysUseUserChoosenMethod() throws URISyntaxException {
-        HttpMethods method = HttpProducerHelper.createMethod(
+        HttpMethods method = HttpHelper.createMethod(
                 createExchangeWithOptionalHttpQueryAndHttpMethodHeader("q=camel", HttpMethods.POST),
                 createHttpEndpoint(true, "http://www.google.com/search"),
                 false);
@@ -89,7 +89,7 @@ public class HttpProducerHelperTest {
 
     @Test
     public void createMethodUseGETIfQueryIsProvidedInHeader() throws URISyntaxException {
-        HttpMethods method = HttpProducerHelper.createMethod(
+        HttpMethods method = HttpHelper.createMethod(
                 createExchangeWithOptionalHttpQueryAndHttpMethodHeader("q=camel", null),
                 createHttpEndpoint(true, "http://www.google.com/search"),
                 false);
@@ -99,7 +99,7 @@ public class HttpProducerHelperTest {
 
     @Test
     public void createMethodUseGETIfQueryIsProvidedInEndpointURI() throws URISyntaxException {
-        HttpMethods method = HttpProducerHelper.createMethod(
+        HttpMethods method = HttpHelper.createMethod(
                 createExchangeWithOptionalHttpQueryAndHttpMethodHeader(null, null),
                 createHttpEndpoint(true, "http://www.google.com/search?q=test"),
                 false);
@@ -109,7 +109,7 @@ public class HttpProducerHelperTest {
 
     @Test
     public void createMethodUseGETIfNoneQueryOrPayloadIsProvided() throws URISyntaxException {
-        HttpMethods method = HttpProducerHelper.createMethod(
+        HttpMethods method = HttpHelper.createMethod(
                 createExchangeWithOptionalHttpQueryAndHttpMethodHeader(null, null),
                 createHttpEndpoint(true, "http://www.google.com/search"),
                 false);
@@ -119,7 +119,7 @@ public class HttpProducerHelperTest {
 
     @Test
     public void createMethodUsePOSTIfNoneQueryButPayloadIsProvided() throws URISyntaxException {
-        HttpMethods method = HttpProducerHelper.createMethod(
+        HttpMethods method = HttpHelper.createMethod(
                 createExchangeWithOptionalHttpQueryAndHttpMethodHeader(null, null),
                 createHttpEndpoint(true, "http://www.google.com/search"),
                 true);

Propchange: camel/trunk/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpHelperTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpHelperTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/DefaultJettyHttpBinding.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/DefaultJettyHttpBinding.java?rev=1053667&r1=1053666&r2=1053667&view=diff
==============================================================================
--- camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/DefaultJettyHttpBinding.java (original)
+++ camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/DefaultJettyHttpBinding.java Wed Dec 29 16:21:05 2010
@@ -17,12 +17,16 @@
 package org.apache.camel.component.jetty;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.Map;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.component.http.HttpConstants;
 import org.apache.camel.component.http.HttpHeaderFilterStrategy;
 import org.apache.camel.component.http.HttpOperationFailedException;
+import org.apache.camel.component.http.helper.HttpHelper;
 import org.apache.camel.spi.HeaderFilterStrategy;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -35,6 +39,7 @@ public class DefaultJettyHttpBinding imp
     private static final transient Log LOG = LogFactory.getLog(DefaultJettyHttpBinding.class);
     private HeaderFilterStrategy headerFilterStrategy = new HttpHeaderFilterStrategy();
     private boolean throwExceptionOnFailure;
+    private boolean transferException;
 
     public void populateResponse(Exchange exchange, JettyContentExchange httpExchange) throws Exception {
         int responseCode = httpExchange.getResponseStatus();
@@ -74,13 +79,20 @@ public class DefaultJettyHttpBinding imp
         this.throwExceptionOnFailure = throwExceptionOnFailure;
     }
 
+    public boolean isTransferException() {
+        return transferException;
+    }
+
+    public void setTransferException(boolean transferException) {
+        this.transferException = transferException;
+    }
+
     protected void populateResponse(Exchange exchange, JettyContentExchange httpExchange,
                                     Message in, HeaderFilterStrategy strategy, int responseCode) throws IOException {
         Message answer = exchange.getOut();
 
         answer.setHeaders(in.getHeaders());
         answer.setHeader(Exchange.HTTP_RESPONSE_CODE, responseCode);
-        answer.setBody(extractResponseBody(exchange, httpExchange));
 
         // propagate HTTP response headers
         // must use entrySet to ensure case of keys is preserved
@@ -94,33 +106,61 @@ public class DefaultJettyHttpBinding imp
                 answer.setHeader(name, value);
             }
         }
+
+        // extract body after headers has been set as we want to ensure content-type from Jetty HttpExchange
+        // has been populated first
+        answer.setBody(extractResponseBody(exchange, httpExchange));
     }
 
-    protected HttpOperationFailedException populateHttpOperationFailedException(Exchange exchange, JettyContentExchange httpExchange,
+    protected Exception populateHttpOperationFailedException(Exchange exchange, JettyContentExchange httpExchange,
                                                                                 int responseCode) throws IOException {
-        HttpOperationFailedException exception;
+        HttpOperationFailedException answer;
         String uri = httpExchange.getUrl();
         Map<String, String> headers = httpExchange.getHeaders();
-        String body = extractResponseBody(exchange, httpExchange);
+        Object responseBody = extractResponseBody(exchange, httpExchange);
+
+        if (transferException && responseBody != null && responseBody instanceof Exception) {
+            // if the response was a serialized exception then use that
+            return (Exception) responseBody;
+        }
+
+        // make a defensive copy of the response body in the exception so its detached from the cache
+        String copy = null;
+        if (responseBody != null) {
+            copy = exchange.getContext().getTypeConverter().convertTo(String.class, exchange, responseBody);
+        }
 
         if (responseCode >= 300 && responseCode < 400) {
             String locationHeader = httpExchange.getResponseFields().getStringField("location");
             if (locationHeader != null) {
-                exception = new HttpOperationFailedException(uri, responseCode, null, locationHeader, headers, body);
+                answer = new HttpOperationFailedException(uri, responseCode, null, locationHeader, headers, copy);
             } else {
                 // no redirect location
-                exception = new HttpOperationFailedException(uri, responseCode, null, null, headers, body);
+                answer = new HttpOperationFailedException(uri, responseCode, null, null, headers, copy);
             }
         } else {
             // internal server error (error code 500)
-            exception = new HttpOperationFailedException(uri, responseCode, null, null, headers, body);
+            answer = new HttpOperationFailedException(uri, responseCode, null, null, headers, copy);
         }
 
-        return exception;
+        return answer;
     }
 
-    protected String extractResponseBody(Exchange exchange, JettyContentExchange httpExchange) throws IOException {
-        return httpExchange.getBody();
+    protected Object extractResponseBody(Exchange exchange, JettyContentExchange httpExchange) throws IOException {
+        String contentType = httpExchange.getHeaders().get(Exchange.CONTENT_TYPE);
+
+        // if content type is serialized java object, then de-serialize it to a Java object
+        if (contentType != null && HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType)) {
+            try {
+                InputStream is = exchange.getContext().getTypeConverter().mandatoryConvertTo(InputStream.class, httpExchange.getResponseContentBytes());
+                return HttpHelper.deserializeJavaObjectFromStream(is);
+            } catch (Exception e) {
+                throw new RuntimeCamelException("Cannot deserialize body to Java object", e);
+            }
+        } else {
+            // just grab the content as string
+            return httpExchange.getBody();
+        }
     }
 
 }

Modified: camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyContentExchange.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyContentExchange.java?rev=1053667&r1=1053666&r2=1053667&view=diff
==============================================================================
--- camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyContentExchange.java (original)
+++ camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyContentExchange.java Wed Dec 29 16:21:05 2010
@@ -115,19 +115,6 @@ public class JettyContentExchange extend
         }
     }
 
-    protected int waitForDoneOrFailure() throws InterruptedException {
-        // just wait a little longer than Jetty itself to be safe
-        // as this timeout is a failsafe in case for some reason Jetty does not callback
-        long timeout = client.getTimeout() + 5000;
-
-        if (LOG.isTraceEnabled()) {
-            LOG.trace("Waiting for done or failure with timeout: " + timeout);
-        }
-        done.await(timeout, TimeUnit.MILLISECONDS);
-
-        return getStatus();
-    }
-
     public Map<String, String> getHeaders() {
         return headers;
     }

Modified: camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpBinding.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpBinding.java?rev=1053667&r1=1053666&r2=1053667&view=diff
==============================================================================
--- camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpBinding.java (original)
+++ camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpBinding.java Wed Dec 29 16:21:05 2010
@@ -67,4 +67,20 @@ public interface JettyHttpBinding {
      */
     boolean isThrowExceptionOnFailure();
 
+    /**
+     * Whether to transfer exception back as a serialized java object
+     * if processing failed due to an exception
+     *
+     * @param transferException <tt>true</tt> to transfer exception
+     */
+    void setTransferException(boolean transferException);
+
+    /**
+     * Whether to transfer exception back as a serialized java object
+     * if processing failed due to an exception
+     *
+     * @return <tt>true</tt> to transfer exception
+     */
+    boolean isTransferException();
+
 }

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=1053667&r1=1053666&r2=1053667&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 Wed Dec 29 16:21:05 2010
@@ -131,6 +131,7 @@ public class JettyHttpComponent extends 
         HttpBinding binding = resolveAndRemoveReferenceParameter(parameters, "httpBindingRef", HttpBinding.class);
         JettyHttpBinding jettyBinding = resolveAndRemoveReferenceParameter(parameters, "jettyHttpBindingRef", JettyHttpBinding.class);
         Boolean throwExceptionOnFailure = getAndRemoveParameter(parameters, "throwExceptionOnFailure", Boolean.class);
+        Boolean transferException = getAndRemoveParameter(parameters, "transferException", Boolean.class);
         Boolean bridgeEndpoint = getAndRemoveParameter(parameters, "bridgeEndpoint", Boolean.class);
         Boolean matchOnUriPrefix = getAndRemoveParameter(parameters, "matchOnUriPrefix", Boolean.class);
         Boolean enableJmx = getAndRemoveParameter(parameters, "enableJmx", Boolean.class);
@@ -188,6 +189,10 @@ public class JettyHttpComponent extends 
         if (throwExceptionOnFailure != null) {
             endpoint.setThrowExceptionOnFailure(throwExceptionOnFailure);
         }
+        // should we transfer exception as serialized object
+        if (transferException != null) {
+            endpoint.setTransferException(transferException);
+        }
         if (bridgeEndpoint != null) {
             endpoint.setBridgeEndpoint(bridgeEndpoint);
         }

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=1053667&r1=1053666&r2=1053667&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 Wed Dec 29 16:21:05 2010
@@ -101,6 +101,7 @@ public class JettyHttpEndpoint extends H
             jettyBinding = new DefaultJettyHttpBinding();
             jettyBinding.setHeaderFilterStrategy(getHeaderFilterStrategy());
             jettyBinding.setThrowExceptionOnFailure(isThrowExceptionOnFailure());
+            jettyBinding.setTransferException(isTransferException());
         }
         return jettyBinding;
     }

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=1053667&r1=1053666&r2=1053667&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 Wed Dec 29 16:21:05 2010
@@ -16,8 +16,10 @@
  */
 package org.apache.camel.component.jetty;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.Serializable;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.Map;
@@ -27,14 +29,17 @@ import org.apache.camel.AsyncProcessor;
 import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
+import org.apache.camel.component.http.HttpConstants;
 import org.apache.camel.component.http.HttpMethods;
-import org.apache.camel.component.http.helper.HttpProducerHelper;
+import org.apache.camel.component.http.helper.HttpHelper;
 import org.apache.camel.impl.DefaultProducer;
 import org.apache.camel.spi.HeaderFilterStrategy;
 import org.apache.camel.util.AsyncProcessorHelper;
 import org.apache.camel.util.ExchangeHelper;
+import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.URISupport;
+import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.eclipse.jetty.client.HttpClient;
@@ -81,8 +86,8 @@ public class JettyHttpProducer extends D
     }
 
     protected JettyContentExchange createHttpExchange(Exchange exchange, AsyncCallback callback) throws Exception {
-        String url = HttpProducerHelper.createURL(exchange, getEndpoint());
-        HttpMethods methodToUse = HttpProducerHelper.createMethod(exchange, getEndpoint(), exchange.getIn().getBody() != null);
+        String url = HttpHelper.createURL(exchange, getEndpoint());
+        HttpMethods methodToUse = HttpHelper.createMethod(exchange, getEndpoint(), exchange.getIn().getBody() != null);
         String method = methodToUse.createMethod(url).getName();
 
         JettyContentExchange httpExchange = new JettyContentExchange(exchange, getBinding(), client);
@@ -100,19 +105,29 @@ public class JettyHttpProducer extends D
                 httpExchange.setRequestContentType(contentType);
             }
 
-            // try with String at first
-            String data = exchange.getIn().getBody(String.class);
-            if (data != null) {
-                String charset = exchange.getProperty(Exchange.CHARSET_NAME, String.class);
-                if (charset != null) {
-                    httpExchange.setRequestContent(new ByteArrayBuffer(data, charset));
+            if (contentType != null && HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType)) {
+                // serialized java object
+                Serializable obj = exchange.getIn().getMandatoryBody(Serializable.class);
+                // write object to output stream
+                ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                HttpHelper.writeObjectToStream(bos, obj);
+                httpExchange.setRequestContent(new ByteArrayBuffer(bos.toByteArray()));
+                IOHelper.close(bos);
+            } else {
+                // try with String at first
+                String data = exchange.getIn().getBody(String.class);
+                if (data != null) {
+                    String charset = exchange.getProperty(Exchange.CHARSET_NAME, String.class);
+                    if (charset != null) {
+                        httpExchange.setRequestContent(new ByteArrayBuffer(data, charset));
+                    } else {
+                        httpExchange.setRequestContent(new ByteArrayBuffer(data));
+                    }
                 } else {
-                    httpExchange.setRequestContent(new ByteArrayBuffer(data));
+                    // then fallback to input stream
+                    InputStream is = exchange.getContext().getTypeConverter().mandatoryConvertTo(InputStream.class, exchange, exchange.getIn().getBody());
+                    httpExchange.setRequestContentSource(is);
                 }
-            } else {
-                // then fallback to input stream
-                InputStream is = exchange.getContext().getTypeConverter().mandatoryConvertTo(InputStream.class, exchange, exchange.getIn().getBody());
-                httpExchange.setRequestContentSource(is);
             }
         }
 

Added: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/javabody/HttpJavaBodyTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/javabody/HttpJavaBodyTest.java?rev=1053667&view=auto
==============================================================================
--- camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/javabody/HttpJavaBodyTest.java (added)
+++ camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/javabody/HttpJavaBodyTest.java Wed Dec 29 16:21:05 2010
@@ -0,0 +1,126 @@
+/**
+ * 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.javabody;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.http.HttpConstants;
+import org.apache.camel.component.jetty.BaseJettyTest;
+import org.junit.Test;
+
+/**
+ * @version $Revision$
+ */
+public class HttpJavaBodyTest extends BaseJettyTest {
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    @Test
+    public void testHttpSendJavaBodyAndReceiveString() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("jetty:http://localhost:{{port}}/myapp/myservice")
+                    .process(new Processor() {
+                        public void process(Exchange exchange) throws Exception {
+                            MyCoolBean cool = exchange.getIn().getBody(MyCoolBean.class);
+                            assertNotNull(cool);
+
+                            assertEquals(123, cool.getId());
+                            assertEquals("Camel", cool.getName());
+
+                            // we send back plain test
+                            exchange.getOut().setHeader(Exchange.CONTENT_TYPE, "text/plain");
+                            exchange.getOut().setBody("OK");
+                        }
+                    });
+            }
+        });
+        context.start();
+
+        MyCoolBean cool = new MyCoolBean(123, "Camel");
+
+        String reply = template.requestBodyAndHeader("http://localhost:{{port}}/myapp/myservice", cool,
+                Exchange.CONTENT_TYPE, HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT, String.class);
+
+        assertEquals("OK", reply);
+    }
+
+    @Test
+    public void testHttpSendJavaBodyAndReceiveJavaBody() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("jetty:http://localhost:{{port}}/myapp/myservice")
+                    .process(new Processor() {
+                        public void process(Exchange exchange) throws Exception {
+                            MyCoolBean cool = exchange.getIn().getBody(MyCoolBean.class);
+                            assertNotNull(cool);
+
+                            assertEquals(123, cool.getId());
+                            assertEquals("Camel", cool.getName());
+
+                            MyCoolBean reply = new MyCoolBean(456, "Camel rocks");
+                            exchange.getOut().setBody(reply);
+                            exchange.getOut().setHeader(Exchange.CONTENT_TYPE, HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT);
+                        }
+                    });
+            }
+        });
+        context.start();
+
+        MyCoolBean cool = new MyCoolBean(123, "Camel");
+
+        MyCoolBean reply = template.requestBodyAndHeader("http://localhost:{{port}}/myapp/myservice", cool,
+                Exchange.CONTENT_TYPE, HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT, MyCoolBean.class);
+
+        assertEquals(456, reply.getId());
+        assertEquals("Camel rocks", reply.getName());
+    }
+
+    @Test
+    public void testHttpSendStringAndReceiveJavaBody() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("jetty:http://localhost:{{port}}/myapp/myservice")
+                    .process(new Processor() {
+                        public void process(Exchange exchange) throws Exception {
+                            String body = exchange.getIn().getBody(String.class);
+                            assertNotNull(body);
+                            assertEquals("Hello World", body);
+
+                            MyCoolBean reply = new MyCoolBean(456, "Camel rocks");
+                            exchange.getOut().setBody(reply);
+                            exchange.getOut().setHeader(Exchange.CONTENT_TYPE, HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT);
+                        }
+                    });
+            }
+        });
+        context.start();
+
+        MyCoolBean reply = template.requestBody("http://localhost:{{port}}/myapp/myservice", "Hello World", MyCoolBean.class);
+
+        assertEquals(456, reply.getId());
+        assertEquals("Camel rocks", reply.getName());
+    }
+
+}

Added: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/javabody/MyCoolBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/javabody/MyCoolBean.java?rev=1053667&view=auto
==============================================================================
--- camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/javabody/MyCoolBean.java (added)
+++ camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/javabody/MyCoolBean.java Wed Dec 29 16:21:05 2010
@@ -0,0 +1,41 @@
+/**
+ * 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.javabody;
+
+import java.io.Serializable;
+
+/**
+ * @version $Revision$
+ */
+public class MyCoolBean implements Serializable {
+
+    private final int id;
+    private final String name;
+
+    public MyCoolBean(int id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+}

Added: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerJavaBodyTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerJavaBodyTest.java?rev=1053667&view=auto
==============================================================================
--- camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerJavaBodyTest.java (added)
+++ camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerJavaBodyTest.java Wed Dec 29 16:21:05 2010
@@ -0,0 +1,126 @@
+/**
+ * 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.jettyproducer;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.http.HttpConstants;
+import org.apache.camel.component.jetty.BaseJettyTest;
+import org.junit.Test;
+
+/**
+ * @version $Revision$
+ */
+public class JettyHttpProducerJavaBodyTest extends BaseJettyTest {
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    @Test
+    public void testHttpSendJavaBodyAndReceiveString() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("jetty:http://localhost:{{port}}/myapp/myservice")
+                    .process(new Processor() {
+                        public void process(Exchange exchange) throws Exception {
+                            MyCoolBean cool = exchange.getIn().getBody(MyCoolBean.class);
+                            assertNotNull(cool);
+
+                            assertEquals(123, cool.getId());
+                            assertEquals("Camel", cool.getName());
+
+                            // we send back plain test
+                            exchange.getOut().setHeader(Exchange.CONTENT_TYPE, "text/plain");
+                            exchange.getOut().setBody("OK");
+                        }
+                    });
+            }
+        });
+        context.start();
+
+        MyCoolBean cool = new MyCoolBean(123, "Camel");
+
+        String reply = template.requestBodyAndHeader("jetty:http://localhost:{{port}}/myapp/myservice", cool,
+                Exchange.CONTENT_TYPE, HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT, String.class);
+
+        assertEquals("OK", reply);
+    }
+
+    @Test
+    public void testHttpSendJavaBodyAndReceiveJavaBody() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("jetty:http://localhost:{{port}}/myapp/myservice")
+                    .process(new Processor() {
+                        public void process(Exchange exchange) throws Exception {
+                            MyCoolBean cool = exchange.getIn().getBody(MyCoolBean.class);
+                            assertNotNull(cool);
+
+                            assertEquals(123, cool.getId());
+                            assertEquals("Camel", cool.getName());
+
+                            MyCoolBean reply = new MyCoolBean(456, "Camel rocks");
+                            exchange.getOut().setBody(reply);
+                            exchange.getOut().setHeader(Exchange.CONTENT_TYPE, HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT);
+                        }
+                    });
+            }
+        });
+        context.start();
+
+        MyCoolBean cool = new MyCoolBean(123, "Camel");
+
+        MyCoolBean reply = template.requestBodyAndHeader("jetty:http://localhost:{{port}}/myapp/myservice", cool,
+                Exchange.CONTENT_TYPE, HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT, MyCoolBean.class);
+
+        assertEquals(456, reply.getId());
+        assertEquals("Camel rocks", reply.getName());
+    }
+
+    @Test
+    public void testHttpSendStringAndReceiveJavaBody() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("jetty:http://localhost:{{port}}/myapp/myservice")
+                    .process(new Processor() {
+                        public void process(Exchange exchange) throws Exception {
+                            String body = exchange.getIn().getBody(String.class);
+                            assertNotNull(body);
+                            assertEquals("Hello World", body);
+
+                            MyCoolBean reply = new MyCoolBean(456, "Camel rocks");
+                            exchange.getOut().setBody(reply);
+                            exchange.getOut().setHeader(Exchange.CONTENT_TYPE, HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT);
+                        }
+                    });
+            }
+        });
+        context.start();
+
+        MyCoolBean reply = template.requestBody("http://localhost:{{port}}/myapp/myservice", "Hello World", MyCoolBean.class);
+
+        assertEquals(456, reply.getId());
+        assertEquals("Camel rocks", reply.getName());
+    }
+
+}

Added: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerTransferExceptionTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerTransferExceptionTest.java?rev=1053667&view=auto
==============================================================================
--- camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerTransferExceptionTest.java (added)
+++ camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerTransferExceptionTest.java Wed Dec 29 16:21:05 2010
@@ -0,0 +1,50 @@
+/**
+ * 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.jettyproducer;
+
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.jetty.BaseJettyTest;
+import org.junit.Test;
+
+/**
+ * @version $Revision$
+ */
+public class JettyHttpProducerTransferExceptionTest extends BaseJettyTest {
+
+    @Test
+    public void testTransferException() throws Exception {
+        try {
+            template.requestBody("jetty:http://localhost:{{port}}/myapp/myservice?transferException=true", "");
+            fail("Should have thrown exception");
+        } catch (CamelExecutionException e) {
+            IllegalArgumentException cause = assertIsInstanceOf(IllegalArgumentException.class, e.getCause());
+            assertEquals("Damn", cause.getMessage());
+        }
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("jetty:http://localhost:{{port}}/myapp/myservice?transferException=true")
+                    .throwException(new IllegalArgumentException("Damn"));
+            }
+        };
+    }
+}

Added: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/MyCoolBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/MyCoolBean.java?rev=1053667&view=auto
==============================================================================
--- camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/MyCoolBean.java (added)
+++ camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/MyCoolBean.java Wed Dec 29 16:21:05 2010
@@ -0,0 +1,41 @@
+/**
+ * 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.jettyproducer;
+
+import java.io.Serializable;
+
+/**
+ * @version $Revision$
+ */
+public class MyCoolBean implements Serializable {
+
+    private final int id;
+    private final String name;
+
+    public MyCoolBean(int id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+}

Modified: camel/trunk/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java?rev=1053667&r1=1053666&r2=1053667&view=diff
==============================================================================
--- camel/trunk/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java (original)
+++ camel/trunk/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java Wed Dec 29 16:21:05 2010
@@ -70,6 +70,9 @@ public class ServletComponent extends Ht
         HttpClientConfigurer configurer = createHttpClientConfigurer(parameters, authMethods);
 
         // must extract well known parameters before we create the endpoint
+        Boolean throwExceptionOnFailure = getAndRemoveParameter(parameters, "throwExceptionOnFailure", Boolean.class);
+        Boolean transferException = getAndRemoveParameter(parameters, "transferException", Boolean.class);
+        Boolean bridgeEndpoint = getAndRemoveParameter(parameters, "bridgeEndpoint", Boolean.class);
         HttpBinding binding = resolveAndRemoveReferenceParameter(parameters, "httpBindingRef", HttpBinding.class);
         Boolean matchOnUriPrefix = getAndRemoveParameter(parameters, "matchOnUriPrefix", Boolean.class);
 
@@ -88,6 +91,17 @@ public class ServletComponent extends Ht
         if (binding != null) {
             endpoint.setBinding(binding);
         }
+        // should we use an exception for failed error codes?
+        if (throwExceptionOnFailure != null) {
+            endpoint.setThrowExceptionOnFailure(throwExceptionOnFailure);
+        }
+        // should we transfer exception as serialized object
+        if (transferException != null) {
+            endpoint.setTransferException(transferException);
+        }
+        if (bridgeEndpoint != null) {
+            endpoint.setBridgeEndpoint(bridgeEndpoint);
+        }
         if (matchOnUriPrefix != null) {
             endpoint.setMatchOnUriPrefix(matchOnUriPrefix);
         }

Added: camel/trunk/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletTransferExceptionTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletTransferExceptionTest.java?rev=1053667&view=auto
==============================================================================
--- camel/trunk/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletTransferExceptionTest.java (added)
+++ camel/trunk/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletTransferExceptionTest.java Wed Dec 29 16:21:05 2010
@@ -0,0 +1,61 @@
+/**
+ * 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.io.ByteArrayInputStream;
+
+import com.meterware.httpunit.PostMethodWebRequest;
+import com.meterware.httpunit.WebRequest;
+import com.meterware.httpunit.WebResponse;
+import com.meterware.servletunit.ServletUnitClient;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.http.HttpConstants;
+import org.apache.camel.component.http.helper.HttpHelper;
+import org.junit.Test;
+
+/**
+ * @version $Revision$
+ */
+public class ServletTransferExceptionTest extends ServletCamelRouterTestSupport {
+
+    @Test
+    public void testTransferException() throws Exception {
+        WebRequest req = new PostMethodWebRequest(CONTEXT_URL + "/services/hello", new ByteArrayInputStream("".getBytes()), "text/plain");
+        ServletUnitClient client = newClient();
+        client.setExceptionsThrownOnErrorStatus(false);
+        WebResponse response = client.getResponse(req);
+
+        assertEquals(500, response.getResponseCode());
+        assertEquals(HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT, response.getContentType());
+        Object object = HttpHelper.deserializeJavaObjectFromStream(response.getInputStream());
+        assertNotNull(object);
+
+        IllegalArgumentException cause = assertIsInstanceOf(IllegalArgumentException.class, object);
+        assertEquals("Damn", cause.getMessage());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("servlet:///hello?transferException=true")
+                    .throwException(new IllegalArgumentException("Damn"));
+            }
+        };
+    }
+}