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 2008/11/21 19:09:19 UTC

svn commit: r719662 - in /activemq/camel/trunk/components: camel-http/src/main/java/org/apache/camel/component/http/ camel-jetty/src/main/java/org/apache/camel/component/jetty/ camel-jetty/src/test/data/ camel-jetty/src/test/java/org/apache/camel/compo...

Author: davsclaus
Date: Fri Nov 21 10:09:17 2008
New Revision: 719662

URL: http://svn.apache.org/viewvc?rev=719662&view=rev
Log:
CAMEL-1107, CAMEL-1083, CAMEL-1095, CAMEL-1093: Major improvements to camel-jetty and camel-http.
camel-jetty: Now properly returns fault and exception
camel-http: repsonse body is avaiable on HttpOperationFailedException
camel-jetty: introduce HttpBinding as interface and to be referenced in Registry for end users to customize how response should be written
camel-jetty: now returns content-type and content-length if possible to calculate
both: minor URI parsing so internal Camel options is not exposed

Added:
    activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java   (contents, props changed)
      - copied, changed from r719340, activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpBinding.java
    activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpBinding.java
    activemq/camel/trunk/components/camel-jetty/src/test/data/
    activemq/camel/trunk/components/camel-jetty/src/test/data/logo.jpeg   (with props)
    activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyContentTypeTest.java
    activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpBindingRefTest.java
    activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpClientOptionsTest.java
    activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyImageFileTest.java
    activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyResponseBodyWhenErrorTest.java   (contents, props changed)
      - copied, changed from r714221, activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyRouteTest.java
Modified:
    activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java
    activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpEndpoint.java
    activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpMessage.java
    activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpOperationFailedException.java
    activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java
    activemq/camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java

Copied: activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java (from r719340, activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpBinding.java)
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java?p2=activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java&p1=activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpBinding.java&r1=719340&r2=719662&rev=719662&view=diff
==============================================================================
--- activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpBinding.java (original)
+++ activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java Fri Nov 21 10:09:17 2008
@@ -18,82 +18,124 @@
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
+import java.io.PrintWriter;
 
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.camel.Message;
-import org.apache.camel.impl.DefaultHeaderFilterStrategy;
 import org.apache.camel.spi.HeaderFilterStrategy;
 
 /**
+ * Binding between {@link HttpMessage} and {@link HttpServletResponse}.
+ *
  * @version $Revision$
  */
-public class HttpBinding {
+public class DefaultHttpBinding implements HttpBinding {
 
     private boolean useReaderForPayload;
     private HeaderFilterStrategy headerFilterStrategy = new HttpHeaderFilterStrategy();
 
-    public HttpBinding(HeaderFilterStrategy headerFilterStrategy) {
+    public DefaultHttpBinding() {
+    }
+
+    public DefaultHttpBinding(HeaderFilterStrategy headerFilterStrategy) {
         this.headerFilterStrategy = headerFilterStrategy;
     }
 
-    /**
-     * Writes the exchange to the servlet response
-     */
+    public void readRequest(HttpServletRequest request, HttpMessage message) {
+        // lets force a parse of the body and headers
+        message.getBody();
+        message.getHeaders();
+    }
+
     public void writeResponse(HttpExchange exchange, HttpServletResponse response) throws IOException {
-        Message out = exchange.getOut();
-        if (out != null) {
-            // Set the status code in the response. Default is 200.
-            if (out.getHeader(HttpProducer.HTTP_RESPONSE_CODE) != null) {
-                int code = out.getHeader(HttpProducer.HTTP_RESPONSE_CODE, Integer.class);
-                response.setStatus(code);
+        if (exchange.isFailed()) {
+            Message fault = exchange.getFault(false);
+            if (fault != null) {
+                doWriteFaultResponse(fault, response);
+            } else {
+                doWriteExceptionResponse(exchange.getException(), response);
             }
-
-            // Write out the headers
-            for (String key : out.getHeaders().keySet()) {
-                String value = out.getHeader(key, String.class);
-                if (headerFilterStrategy != null
-                        && !headerFilterStrategy.applyFilterToCamelHeaders(key, value)) {
-                    response.setHeader(key, value);
-                }
+        } else {
+            Message out = exchange.getOut();
+            if (out != null) {
+                doWriteResponse(out, response);
             }
+        }
+    }
 
-            // Write out the body.
-            if (out.getBody() != null) {
+    public void doWriteExceptionResponse(Throwable exception, HttpServletResponse response) throws IOException {
+        response.setStatus(500); // 500 for internal server error
+        response.setContentType("text/plain");
+
+        // append the stacktrace as response
+        PrintWriter pw = response.getWriter();
+        exception.printStackTrace(pw);
 
-                // Try to stream the body since that would be the most efficient
-                InputStream is = out.getBody(InputStream.class);
-                if (is != null) {
-                    ServletOutputStream os = null;
-                    try {
-                        os = response.getOutputStream();
-                        int c;
-                        while ((c = is.read()) >= 0) {
-                            os.write(c);
-                        }
-                        os.flush();
-                    } finally {
-                        os.close();
-                        is.close();
-                    }
-                } else {
-                    String data = out.getBody(String.class);
-                    if (data != null) {
-                        response.getWriter().print(data);
+        pw.flush();
+    }
+
+    public void doWriteFaultResponse(Message message, HttpServletResponse response) throws IOException {
+        doWriteResponse(message, response);
+    }
+
+    public void doWriteResponse(Message message, HttpServletResponse response) throws IOException {
+        // set the status code in the response. Default is 200.
+        if (message.getHeader(HttpProducer.HTTP_RESPONSE_CODE) != null) {
+            int code = message.getHeader(HttpProducer.HTTP_RESPONSE_CODE, Integer.class);
+            response.setStatus(code);
+        }
+        // set the content type in the response.
+        if (message.getHeader("Content-Type") != null) {
+            String contentType = message.getHeader("Content-Type", String.class);
+            response.setContentType(contentType);
+        }
+
+        // append headers
+        for (String key : message.getHeaders().keySet()) {
+            String value = message.getHeader(key, String.class);
+            if (headerFilterStrategy != null
+                    && !headerFilterStrategy.applyFilterToCamelHeaders(key, value)) {
+                response.setHeader(key, value);
+            }
+        }
+
+        // write the body.
+        if (message.getBody() != null) {
+            // try to stream the body since that would be the most efficient
+            InputStream is = message.getBody(InputStream.class);
+            int length = 0;
+            if (is != null) {
+                ServletOutputStream os = null;
+                try {
+                    os = response.getOutputStream();
+                    int c;
+                    while ((c = is.read()) >= 0) {
+                        os.write(c);
+                        length++;
                     }
+                    // set content length before we flush
+                    response.setContentLength(length);
+                    os.flush();
+                } finally {
+                    os.close();
+                    is.close();
+                }
+            } else {
+                String data = message.getBody(String.class);
+                if (data != null) {
+                    // set content length before we write data
+                    response.setContentLength(data.length());
+                    response.getWriter().print(data);
+                    response.getWriter().flush();
                 }
             }
+
         }
     }
 
-    /**
-     * Parses the body from a HTTP message
-     */
     public Object parseBody(HttpMessage httpMessage) throws IOException {
         // lets assume the body is a reader
         HttpServletRequest request = httpMessage.getRequest();
@@ -108,12 +150,15 @@
         return useReaderForPayload;
     }
 
-    /**
-     * Should the {@link HttpServletRequest#getReader()} be exposed as the payload of input messages in the Camel
-     * {@link Message#getBody()} or not. If false then the {@link HttpServletRequest#getInputStream()} will be exposed.
-     */
     public void setUseReaderForPayload(boolean useReaderForPayload) {
         this.useReaderForPayload = useReaderForPayload;
     }
 
+    public HeaderFilterStrategy getHeaderFilterStrategy() {
+        return headerFilterStrategy;
+    }
+
+    public void setHeaderFilterStrategy(HeaderFilterStrategy headerFilterStrategy) {
+        this.headerFilterStrategy = headerFilterStrategy;
+    }
 }

Propchange: activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpBinding.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpBinding.java?rev=719662&view=auto
==============================================================================
--- activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpBinding.java (added)
+++ activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpBinding.java Fri Nov 21 10:09:17 2008
@@ -0,0 +1,97 @@
+package org.apache.camel.component.http;
+
+import java.io.IOException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.camel.Message;
+import org.apache.camel.spi.HeaderFilterStrategy;
+
+/**
+ * A plugable strategy for configuring the http binding so reading request and writing response
+ * can be customized using the Java Servlet API.
+ * <p/>
+ * This is used by the camel-jetty.
+ *
+ * @version $Revision$
+ */
+public interface HttpBinding {
+
+    /**
+     * Startegy to read the given request and bindings it to the given message.
+     *
+     * @param request  the request
+     * @param message  the message to populate with data from request
+     */
+    void readRequest(HttpServletRequest request, HttpMessage message);
+
+    /**
+     * Parses the body from a {@link org.apache.camel.component.http.HttpMessage}
+     *
+     * @return the parsed body returned as either a {@link java.io.InputStream} or a {@link java.io.Reader}
+     * depending on the {@link #setUseReaderForPayload(boolean)} property.
+     * @throws java.io.IOException can be thrown
+     */
+    Object parseBody(HttpMessage httpMessage) throws IOException;
+
+    /**
+     * Writes the exchange to the servlet response.
+     * <p/>
+     * Default implementation will delegate to the following methods depending on the status of the exchange
+     * <ul>
+     *   <li>doWriteResponse - processing returns a OUT message </li>
+     *   <li>doWriteFaultResponse - processing returns a fault message</li>
+     *   <li>doWriteResponse - processing returns an exception and status code 500</li>
+     * </ul>
+     *
+     * @param exchange the exchange
+     * @param response the http response
+     * @throws java.io.IOException can be thrown from http response
+     */
+    void writeResponse(HttpExchange exchange, HttpServletResponse response) throws IOException;
+
+    /**
+     * Strategy method that writes the response to the http response stream when an exception occuerd
+     *
+     * @param exception  the exception occured
+     * @param response   the http response
+     * @throws java.io.IOException can be thrown from http response
+     */
+    void doWriteExceptionResponse(Throwable exception, HttpServletResponse response) throws IOException;
+
+    /**
+     * Strategy method that writes the response to the http response stream for a fault message
+     *
+     * @param message  the fault message
+     * @param response   the http response
+     * @throws java.io.IOException can be thrown from http response
+     */
+    void doWriteFaultResponse(Message message, HttpServletResponse response) throws IOException;
+
+    /**
+     * Strategy method that writes the response to the http response stream for an OUT message
+     *
+     * @param message  the OUT message
+     * @param response   the http response
+     * @throws java.io.IOException can be thrown from http response
+     */
+    void doWriteResponse(Message message, HttpServletResponse response) throws IOException;
+
+    boolean isUseReaderForPayload();
+
+    /**
+     * Should the {@link javax.servlet.http.HttpServletRequest#getReader()} be exposed as the payload of input messages in the Camel
+     * {@link org.apache.camel.Message#getBody()} or not. If false then the {@link javax.servlet.http.HttpServletRequest#getInputStream()} will be exposed.
+     */
+    void setUseReaderForPayload(boolean useReaderForPayload);
+
+    HeaderFilterStrategy getHeaderFilterStrategy();
+
+    /**
+     * Sets the header filter stratety to use.
+     * <p/>
+     * Will default use {@link org.apache.camel.component.http.HttpHeaderFilterStrategy}
+     */
+    void setHeaderFilterStrategy(HeaderFilterStrategy headerFilterStrategy);
+
+}

Modified: activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java?rev=719662&r1=719661&r2=719662&view=diff
==============================================================================
--- activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java (original)
+++ activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java Fri Nov 21 10:09:17 2008
@@ -24,7 +24,9 @@
 import org.apache.camel.ResolveEndpointFailedException;
 import org.apache.camel.impl.DefaultComponent;
 import org.apache.camel.spi.HeaderFilterStrategy;
+import org.apache.camel.util.CamelContextHelper;
 import org.apache.camel.util.IntrospectionSupport;
+import org.apache.camel.util.URISupport;
 import org.apache.commons.httpclient.HttpConnectionManager;
 import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
 import org.apache.commons.httpclient.params.HttpClientParams;
@@ -36,10 +38,10 @@
  * @version $Revision$
  */
 public class HttpComponent extends DefaultComponent implements HeaderFilterStrategyAware {
-
-    private HttpClientConfigurer httpClientConfigurer;
-    private HttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
-    private HeaderFilterStrategy headerFilterStrategy;
+    protected HttpClientConfigurer httpClientConfigurer;
+    protected HttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
+    protected HeaderFilterStrategy headerFilterStrategy;
+    protected HttpBinding httpBinding;
 
     public HttpComponent() {
         this.setHeaderFilterStrategy(new HttpHeaderFilterStrategy());
@@ -47,51 +49,55 @@
     
     /**
      * Connects the URL specified on the endpoint to the specified processor.
+     *
+     * @param  consumer the consumer
+     * @throws Exception can be thrown
      */
     public void connect(HttpConsumer consumer) throws Exception {
     }
 
     /**
-     * Disconnects the URL specified on the endpoint from the specified
-     * processor.
+     * Disconnects the URL specified on the endpoint from the specified processor.
+     *
+     * @param  consumer the consumer
+     * @throws Exception can be thrown
      */
     public void disconnect(HttpConsumer consumer) throws Exception {
     }
 
-    public HttpClientConfigurer getHttpClientConfigurer() {
-        return httpClientConfigurer;
-    }
-
-    public void setHttpClientConfigurer(HttpClientConfigurer httpClientConfigurer) {
-        this.httpClientConfigurer = httpClientConfigurer;
-    }
-
-    public HttpConnectionManager getHttpConnectionManager() {
-        return httpConnectionManager;
-    }
-
-    public void setHttpConnectionManager(HttpConnectionManager httpConnectionManager) {
-        this.httpConnectionManager = httpConnectionManager;
-    }
-
     @Override
     protected Endpoint createEndpoint(String uri, String remaining, Map parameters)
         throws Exception {
+
+        // http client can be configured from URI options
         HttpClientParams params = new HttpClientParams();
         IntrospectionSupport.setProperties(params, parameters, "httpClient.");
 
+        // lookup http binding in registry if provided
+        String ref = getAndRemoveParameter(parameters, "httpBindingRef", String.class);
+        if (ref != null) {
+            httpBinding = CamelContextHelper.mandatoryLookup(getCamelContext(), ref, HttpBinding.class);
+        }
+
+        // restructure uri to be based on the parameters left as we dont want to include the Camel internal options
+        URI httpUri = URISupport.createRemainingURI(new URI(uri), parameters);
+        uri = httpUri.toString();
+
         // validate http uri that end-user did not duplicate the http part that can be a common error
-        URI httpUri = new URI(uri);
         String part = httpUri.getSchemeSpecificPart();
         if (part != null) {
             part = part.toLowerCase();
-            if (part.startsWith("//http://") || part.startsWith("//https://")) {
+            if (part.startsWith("//http//") || part.startsWith("//https//")) {
                 throw new ResolveEndpointFailedException(uri,
-                    "The uri part is not configured correctly. You have duplicated the http(s) protocol.");
+                        "The uri part is not configured correctly. You have duplicated the http(s) protocol.");
             }
         }
 
-        return new HttpEndpoint(uri, this, httpUri, params, httpConnectionManager, httpClientConfigurer);
+        HttpEndpoint endpoint = new HttpEndpoint(uri, this, httpUri, params, httpConnectionManager, httpClientConfigurer);
+        if (httpBinding != null) {
+            endpoint.setBinding(httpBinding);
+        }
+        return endpoint;
     }
 
     @Override
@@ -99,6 +105,22 @@
         return false;
     }
 
+    public HttpClientConfigurer getHttpClientConfigurer() {
+        return httpClientConfigurer;
+    }
+
+    public void setHttpClientConfigurer(HttpClientConfigurer httpClientConfigurer) {
+        this.httpClientConfigurer = httpClientConfigurer;
+    }
+
+    public HttpConnectionManager getHttpConnectionManager() {
+        return httpConnectionManager;
+    }
+
+    public void setHttpConnectionManager(HttpConnectionManager httpConnectionManager) {
+        this.httpConnectionManager = httpConnectionManager;
+    }
+
     public HeaderFilterStrategy getHeaderFilterStrategy() {
         return headerFilterStrategy;
     }
@@ -106,4 +128,12 @@
     public void setHeaderFilterStrategy(HeaderFilterStrategy strategy) {
         headerFilterStrategy = strategy;
     }
+
+    public HttpBinding getHttpBinding() {
+        return httpBinding;
+    }
+
+    public void setHttpBinding(HttpBinding httpBinding) {
+        this.httpBinding = httpBinding;
+    }
 }

Modified: activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpEndpoint.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpEndpoint.java?rev=719662&r1=719661&r2=719662&view=diff
==============================================================================
--- activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpEndpoint.java (original)
+++ activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpEndpoint.java Fri Nov 21 10:09:17 2008
@@ -139,7 +139,7 @@
 
     public HttpBinding getBinding() {
         if (binding == null) {
-            binding = new HttpBinding(getHeaderFilterStrategy());
+            binding = new DefaultHttpBinding(getHeaderFilterStrategy());
         }
         return binding;
     }

Modified: activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpMessage.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpMessage.java?rev=719662&r1=719661&r2=719662&view=diff
==============================================================================
--- activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpMessage.java (original)
+++ activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpMessage.java Fri Nov 21 10:09:17 2008
@@ -35,9 +35,9 @@
         setExchange(exchange);
         this.request = request;
 
-        // lets force a parse of the body and headers
-        getBody();
-        getHeaders();
+        // use binding to read the request allowing end users to use their
+        // implementation of the binding
+        getExchange().getEndpoint().getBinding().readRequest(request, this);
     }
 
     @Override

Modified: activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpOperationFailedException.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpOperationFailedException.java?rev=719662&r1=719661&r2=719662&view=diff
==============================================================================
--- activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpOperationFailedException.java (original)
+++ activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpOperationFailedException.java Fri Nov 21 10:09:17 2008
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.http;
 
+import java.io.InputStream;
+
 import org.apache.camel.CamelException;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.commons.httpclient.StatusLine;
@@ -24,6 +26,7 @@
     private final String redirectLocation;
     private final int statusCode;
     private final StatusLine statusLine;
+    private InputStream responseBody;
 
     public HttpOperationFailedException(int statusCode, StatusLine statusLine, String location) {
         super("HTTP operation failed with statusCode: " + statusCode + ", status: " + statusLine + (location != null ? ", redirectLocation: " + location : ""));
@@ -56,4 +59,11 @@
         return statusCode;
     }
 
+    public InputStream getResponseBody() {
+        return responseBody;
+    }
+
+    public void setResponseBody(InputStream responseBody) {
+        this.responseBody = responseBody;
+    }
 }
\ No newline at end of file

Modified: activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java?rev=719662&r1=719661&r2=719662&view=diff
==============================================================================
--- activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java (original)
+++ activemq/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java Fri Nov 21 10:09:17 2008
@@ -19,9 +19,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
@@ -42,6 +39,7 @@
 import org.apache.commons.logging.LogFactory;
 
 import static org.apache.camel.component.http.HttpMethods.HTTP_METHOD;
+
 /**
  * @version $Revision$
  */
@@ -98,18 +96,24 @@
                 }
             } else {
                 HttpOperationFailedException exception = null;
-                if (responseCode < 400 && responseCode >= 300) {
+                if (responseCode >= 300 && responseCode < 400) {
                     String redirectLocation;
                     Header locationHeader = method.getResponseHeader("location");
                     if (locationHeader != null) {
                         redirectLocation = locationHeader.getValue();
                         exception = new HttpOperationFailedException(responseCode, method.getStatusLine(), redirectLocation);
+                    } else {
+                        // no redirect location
+                        exception = new HttpOperationFailedException(responseCode, method.getStatusLine());
                     }
                 } else {
+                    // internal server error (error code 500)
                     exception = new HttpOperationFailedException(responseCode, method.getStatusLine());
                 }
 
                 if (exception != null) {
+                    // set also the response body as well
+                    exception.setResponseBody(extractResponseBody(method));
                     throw exception;
                 }
             }
@@ -119,14 +123,6 @@
         }
     }
 
-    public HttpClient getHttpClient() {
-        return httpClient;
-    }
-
-    public void setHttpClient(HttpClient httpClient) {
-        this.httpClient = httpClient;
-    }
-
     /**
      * Strategy when executing the method (calling the remote server).
      *
@@ -138,12 +134,23 @@
         return httpClient.executeMethod(method);
     }
 
+    /**
+     * Extracts the response from the method as a InputStream.
+     *
+     * @param method  the method that was executed
+     * @return  the response as a stream
+     * @throws IOException can be thrown
+     */
     protected static InputStream extractResponseBody(HttpMethod method) throws IOException {
         LoadingByteArrayOutputStream bos = null;
         InputStream is = null;
         try {
             bos = new LoadingByteArrayOutputStream();
             is = method.getResponseBodyAsStream();
+            // in case of no response stream
+            if (is == null) {
+                return null;
+            }
             IOUtils.copy(is, bos);
             bos.flush();
             return bos.createInputStream();
@@ -153,6 +160,12 @@
         }
     }
 
+    /**
+     * Creates the HttpMethod to use to call the remote server, either its GET or POST.
+     *
+     * @param exchange  the exchange
+     * @return the created method as either GET or POST
+     */
     protected HttpMethod createMethod(Exchange exchange) {
         // is a query string provided in the endpoint URI or in a header (header overrules endpoint)
         String queryString = exchange.getIn().getHeader(QUERY, String.class);
@@ -179,7 +192,7 @@
         if (uri == null) {
             uri = ((HttpEndpoint)getEndpoint()).getHttpUri().toString();
         }
-        
+
         HttpMethod method = methodToUse.createMethod(uri);
 
         if (queryString != null) {
@@ -192,6 +205,12 @@
         return method;
     }
 
+    /**
+     * 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
+     * @return the data holder
+     */
     protected RequestEntity createRequestEntity(Exchange exchange) {
         Message in = exchange.getIn();
         if (in.getBody() == null) {
@@ -215,4 +234,12 @@
             }
         }
     }
+
+    public HttpClient getHttpClient() {
+        return httpClient;
+    }
+
+    public void setHttpClient(HttpClient httpClient) {
+        this.httpClient = httpClient;
+    }
 }

Modified: activemq/camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java?rev=719662&r1=719661&r2=719662&view=diff
==============================================================================
--- activemq/camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java (original)
+++ activemq/camel/trunk/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java Fri Nov 21 10:09:17 2008
@@ -22,9 +22,13 @@
 
 import org.apache.camel.Endpoint;
 import org.apache.camel.component.http.CamelServlet;
+import org.apache.camel.component.http.HttpBinding;
 import org.apache.camel.component.http.HttpComponent;
 import org.apache.camel.component.http.HttpConsumer;
 import org.apache.camel.component.http.HttpEndpoint;
+import org.apache.camel.util.CamelContextHelper;
+import org.apache.camel.util.IntrospectionSupport;
+import org.apache.camel.util.URISupport;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.mortbay.jetty.Connector;
@@ -65,20 +69,40 @@
         }
     }
     
-    private static final Log LOGGER = LogFactory.getLog(JettyHttpComponent.class);
+    private static final transient Log LOG = LogFactory.getLog(JettyHttpComponent.class);
     
-    private Server server;
-    private HashMap<String, ConnectorRef> connectors = new HashMap<String, ConnectorRef>();
-    private HttpClient httpClient;
-    private String sslKeyPassword;
-    private String sslPassword;
-    private String sslKeystore;
-    private SslSocketConnector sslSocketConnector;
+    protected Server server;
+    protected HashMap<String, ConnectorRef> connectors = new HashMap<String, ConnectorRef>();
+    protected HttpClient httpClient;
+    protected String sslKeyPassword;
+    protected String sslPassword;
+    protected String sslKeystore;
+    protected SslSocketConnector sslSocketConnector;
 
     @Override
     protected Endpoint createEndpoint(String uri, String remaining, Map parameters) throws Exception {
-        URI httpURL = uri.startsWith("jetty:") ? new URI(remaining) : new URI(uri);
-        JettyHttpEndpoint result = new JettyHttpEndpoint(this, uri, httpURL, getHttpConnectionManager());
+        uri = uri.startsWith("jetty:") ? remaining : uri;
+
+        // http client can be configured from URI options
+        if (httpClient == null) {
+            httpClient = createHttpClient();
+        }
+        IntrospectionSupport.setProperties(httpClient, parameters, "httpClient.");
+
+        // lookup http binding in registry if provided
+        String ref = getAndRemoveParameter(parameters, "httpBindingRef", String.class);
+        if (ref != null) {
+            httpBinding = CamelContextHelper.mandatoryLookup(getCamelContext(), ref, HttpBinding.class);
+        }
+
+        // restructure uri to be based on the parameters left as we dont want to include the Camel internal options
+        URI httpUri = URISupport.createRemainingURI(new URI(uri), parameters);
+        uri = httpUri.toString();
+
+        JettyHttpEndpoint result = new JettyHttpEndpoint(this, uri, httpUri, getHttpConnectionManager());
+        if (httpBinding != null) {
+            result.setBinding(httpBinding);
+        }
         setProperties(result, parameters);
         return result;
     }
@@ -90,7 +114,6 @@
      */
     @Override
     public void connect(HttpConsumer consumer) throws Exception {
-
         // Make sure that there is a connector for the requested endpoint.
         JettyHttpEndpoint endpoint = (JettyHttpEndpoint)consumer.getEndpoint();
         String connectorKey = endpoint.getProtocol() + ":" + endpoint.getHttpUri().getHost() + ":" + endpoint.getPort();
@@ -107,7 +130,7 @@
                 connector.setPort(endpoint.getPort());
                 connector.setHost(endpoint.getHttpUri().getHost());
                 if ("localhost".equalsIgnoreCase(endpoint.getHttpUri().getHost())) {
-                    LOGGER.warn("You use localhost interface! It means that no external connections will be available. Don't you want to use 0.0.0.0 instead (all network interfaces)?");
+                    LOG.warn("You use localhost interface! It means that no external connections will be available. Don't you want to use 0.0.0.0 instead (all network interfaces)?");
                 }
                 getServer().addConnector(connector);
 

Added: activemq/camel/trunk/components/camel-jetty/src/test/data/logo.jpeg
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-jetty/src/test/data/logo.jpeg?rev=719662&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/camel/trunk/components/camel-jetty/src/test/data/logo.jpeg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyContentTypeTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyContentTypeTest.java?rev=719662&view=auto
==============================================================================
--- activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyContentTypeTest.java (added)
+++ activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyContentTypeTest.java Fri Nov 21 10:09:17 2008
@@ -0,0 +1,75 @@
+/**
+ * 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.ContextTestSupport;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * Unit test for content-type
+ */
+public class JettyContentTypeTest extends ContextTestSupport {
+
+    public void testSameContentType() throws Exception {
+        Endpoint endpoint = context.getEndpoint("http://localhost:8080/myapp/myservice");
+        Exchange exchange = endpoint.createExchange();
+        exchange.getIn().setBody("<order>123</order>");
+        exchange.getIn().setHeader("user", "Claus");
+        exchange.getIn().setHeader("content-type", "text/xml");
+        template.send(endpoint, exchange);
+
+        String body = exchange.getOut().getBody(String.class);
+        assertEquals("<order>OK</order>", body);
+        assertOutMessageHeader(exchange, "content-type", "text/xml");
+    }
+
+    public void testMixedContentType() throws Exception {
+        Endpoint endpoint = context.getEndpoint("http://localhost:8080/myapp/myservice");
+        Exchange exchange = endpoint.createExchange();
+        exchange.getIn().setBody("<order>123</order>");
+        exchange.getIn().setHeader("Content-Type", "text/xml");
+        template.send(endpoint, exchange);
+
+        String body = exchange.getOut().getBody(String.class);
+        assertEquals("FAIL", body);
+        assertOutMessageHeader(exchange, "Content-Type", "text/plain");
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                from("jetty:http://localhost:8080/myapp/myservice").process(new MyBookService());
+            }
+        };
+    }
+
+    public class MyBookService implements Processor {
+        public void process(Exchange exchange) throws Exception {
+            if (exchange.getIn().getHeader("user") != null) {
+                exchange.getOut().setBody("<order>OK</order>");
+            } else {
+                exchange.getOut().setBody("FAIL");
+                exchange.getOut().setHeader("Content-Type", "text/plain");
+            }
+        }
+    }
+
+}
\ No newline at end of file

Added: activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpBindingRefTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpBindingRefTest.java?rev=719662&view=auto
==============================================================================
--- activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpBindingRefTest.java (added)
+++ activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpBindingRefTest.java Fri Nov 21 10:09:17 2008
@@ -0,0 +1,71 @@
+package org.apache.camel.component.jetty;
+
+import java.io.IOException;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.http.DefaultHttpBinding;
+import org.apache.camel.impl.JndiRegistry;
+
+/**
+ * Unit test for http binding ref option.
+ */
+public class JettyHttpBindingRefTest extends ContextTestSupport {
+
+    public void testDefaultHttpBinding() throws Exception {
+        Object out = template.requestBody("http://localhost:8080/myapp/myservice", "Hello World");
+        assertEquals("Bye World", context.getTypeConverter().convertTo(String.class, out));
+    }
+
+    public void testCustomHttpBinding() throws Exception {
+        Object out = template.requestBody("http://localhost:8081/myapp/myotherservice", "Hello World");
+        assertEquals("Something went wrong but we dont care", context.getTypeConverter().convertTo(String.class, out));
+    }
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry jndi = super.createRegistry();
+        jndi.bind("default", new DefaultHttpBinding());
+        jndi.bind("myownbinder", new MyHttpBinding());
+        return jndi;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                errorHandler(noErrorHandler());
+
+                from("jetty:http://localhost:8080/myapp/myservice?httpBindingRef=default").transform().constant("Bye World");
+
+                from("jetty:http://localhost:8081/myapp/myotherservice?httpBindingRef=myownbinder").process(new Processor() {
+                    public void process(Exchange exchange) throws Exception {
+                        throw new IllegalStateException("Not implemented");
+                    }
+                });
+            }
+        };
+    }
+
+    // START SNIPPET: e1
+    public class MyHttpBinding extends DefaultHttpBinding {
+
+        @Override
+        public void doWriteExceptionResponse(Throwable exception, HttpServletResponse response) throws IOException {
+            // we override the doWriteExceptionResponse as we only want to alter the binding how exceptions is
+            // written back to the client. 
+
+            // we just return HTTP 200 so the client thinks its okay
+            response.setStatus(200);
+            // and we return this fixed text
+            response.getWriter().write("Something went wrong but we dont care");
+        }
+    }
+    // END SNIPPET: e1
+
+}
+

Added: activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpClientOptionsTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpClientOptionsTest.java?rev=719662&view=auto
==============================================================================
--- activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpClientOptionsTest.java (added)
+++ activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpClientOptionsTest.java Fri Nov 21 10:09:17 2008
@@ -0,0 +1,32 @@
+package org.apache.camel.component.jetty;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * Unit test for http client options.
+ */
+public class JettyHttpClientOptionsTest extends ContextTestSupport {
+
+    public void testCustomHttpBinding() throws Exception {
+        // assert jetty was configured with our timeout
+        JettyHttpComponent jetty = context.getComponent("jetty", JettyHttpComponent.class);
+        assertNotNull(jetty);
+        assertEquals(5555, jetty.getHttpClient().getIdleTimeout());
+
+        // send and receive
+        Object out = template.requestBody("http://localhost:8080/myapp/myservice", "Hello World");
+        assertEquals("Bye World", context.getTypeConverter().convertTo(String.class, out));
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("jetty:http://localhost:8080/myapp/myservice?httpClient.idleTimeout=5555").transform().constant("Bye World");
+            }
+        };
+    }
+
+}
\ No newline at end of file

Added: activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyImageFileTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyImageFileTest.java?rev=719662&view=auto
==============================================================================
--- activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyImageFileTest.java (added)
+++ activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyImageFileTest.java Fri Nov 21 10:09:17 2008
@@ -0,0 +1,57 @@
+/**
+ * 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 java.io.File;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * Unit test for exposing a http server that returns images
+ */
+public class JettyImageFileTest extends ContextTestSupport {
+
+    public void testImageContentType() throws Exception {
+        Endpoint endpoint = context.getEndpoint("http://localhost:8080/myapp/myservice");
+        Exchange exchange = endpoint.createExchange();
+        template.send(endpoint, exchange);
+
+        assertNotNull(exchange.getOut().getBody());
+        assertOutMessageHeader(exchange, "Content-Type", "image/jpeg");
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                from("jetty:http://localhost:8080/myapp/myservice").process(new MyImageService());
+            }
+        };
+    }
+
+    public class MyImageService implements Processor {
+        public void process(Exchange exchange) throws Exception {
+            exchange.getOut().setBody(new File("src/test/data/logo.jpeg"));
+            exchange.getOut().setHeader("Content-Type", "image/jpeg");
+        }
+    }
+
+}
\ No newline at end of file

Copied: activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyResponseBodyWhenErrorTest.java (from r714221, activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyRouteTest.java)
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyResponseBodyWhenErrorTest.java?p2=activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyResponseBodyWhenErrorTest.java&p1=activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyRouteTest.java&r1=714221&r2=719662&rev=719662&view=diff
==============================================================================
--- activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyRouteTest.java (original)
+++ activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyResponseBodyWhenErrorTest.java Fri Nov 21 10:09:17 2008
@@ -16,53 +16,45 @@
  */
 package org.apache.camel.component.jetty;
 
-import javax.servlet.http.HttpServletRequest;
-
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
+import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.http.HttpOperationFailedException;
 
 /**
- * Unit test for wiki demonstration.
+ * Unit test for HttpOperationFailedException should contain reponse body
  */
-public class JettyRouteTest extends ContextTestSupport {
+public class JettyResponseBodyWhenErrorTest extends ContextTestSupport {
 
-    public void testSendToJetty() throws Exception {
-        Object response = template.requestBody("http://localhost:8080/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);
+    public void testResponseBodyWhenError() throws Exception {
+        try {
+            template.sendBody("http://localhost:8080/myapp/myservice", "bookid=123");
+            fail("Should have thrown an exception");
+        } catch (RuntimeCamelException e) {
+            HttpOperationFailedException cause = (HttpOperationFailedException) e.getCause();
+            assertEquals(500, cause.getStatusCode());
+            String body = context.getTypeConverter().convertTo(String.class, cause.getResponseBody());
+            assertTrue(body.indexOf("Damm") > -1);
+            assertTrue(body.indexOf("IllegalArgumentException") > -1);
+        }
     }
 
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
             public void configure() throws Exception {
-                // START SNIPPET: e1
+                errorHandler(noErrorHandler());
                 from("jetty:http://localhost:8080/myapp/myservice").process(new MyBookService());
-                // END SNIPPET: e1
             }
         };
     }
 
-    // START SNIPPET: e2
     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(true).setBody("<html><body>Book 123 is Camel in Action</body></html>");
+            throw new IllegalArgumentException("Damm");
         }
     }
-    // END SNIPPET: e2
 
-}
+}
\ No newline at end of file

Propchange: activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyResponseBodyWhenErrorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyResponseBodyWhenErrorTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: activemq/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyResponseBodyWhenErrorTest.java
------------------------------------------------------------------------------
    svn:mergeinfo =