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/27 10:53:45 UTC

svn commit: r1053033 - in /camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4: DefaultHttpBinding.java HttpComponent.java HttpConstants.java HttpEndpoint.java HttpProducer.java

Author: davsclaus
Date: Mon Dec 27 09:53:44 2010
New Revision: 1053033

URL: http://svn.apache.org/viewvc?rev=1053033&view=rev
Log:
CAMEL-3218: Ported changes from camel-http to camel-http4

Added:
    camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpConstants.java
Modified:
    camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/DefaultHttpBinding.java
    camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpComponent.java
    camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEndpoint.java
    camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpProducer.java

Modified: camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/DefaultHttpBinding.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/DefaultHttpBinding.java?rev=1053033&r1=1053032&r2=1053033&view=diff
==============================================================================
--- camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/DefaultHttpBinding.java (original)
+++ camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/DefaultHttpBinding.java Mon Dec 27 09:53:44 2010
@@ -19,15 +19,13 @@ package org.apache.camel.component.http4
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.ObjectOutputStream;
 import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.util.Enumeration;
 import java.util.Map;
-
 import javax.activation.DataHandler;
-import javax.activation.FileDataSource;
-import javax.activation.FileTypeMap;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -54,48 +52,56 @@ public class DefaultHttpBinding implemen
 
     private boolean useReaderForPayload;
     private HeaderFilterStrategy headerFilterStrategy = new HttpHeaderFilterStrategy();
+    private HttpEndpoint endpoint;
 
+    @Deprecated
     public DefaultHttpBinding() {
     }
 
+    @Deprecated
     public DefaultHttpBinding(HeaderFilterStrategy headerFilterStrategy) {
         this.headerFilterStrategy = headerFilterStrategy;
     }
 
+    public DefaultHttpBinding(HttpEndpoint endpoint) {
+        this.endpoint = endpoint;
+        this.headerFilterStrategy = endpoint.getHeaderFilterStrategy();
+    }
+
     public void readRequest(HttpServletRequest request, HttpMessage message) {
 
         // lets force a parse of the body and headers
         message.getBody();
         // populate the headers from the request
         Map<String, Object> headers = message.getHeaders();
-        
+
         //apply the headerFilterStrategy
         Enumeration names = request.getHeaderNames();
         while (names.hasMoreElements()) {
-            String name = (String)names.nextElement();
+            String name = (String) names.nextElement();
             Object value = request.getHeader(name);
             // mapping the content-type 
             if (name.toLowerCase().equals("content-type")) {
                 name = Exchange.CONTENT_TYPE;
             }
             if (headerFilterStrategy != null
-                && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, message.getExchange())) {
+                    && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, message.getExchange())) {
                 headers.put(name, value);
             }
         }
-        
+
         if (request.getCharacterEncoding() != null) {
             headers.put(Exchange.HTTP_CHARACTER_ENCODING, request.getCharacterEncoding());
             message.getExchange().setProperty(Exchange.CHARSET_NAME, request.getCharacterEncoding());
-        }        
+        }
 
-        popluateRequestParameters(request, message);
+        populateRequestParameters(request, message);
         // reset the stream cache
         StreamCache cache = message.getBody(StreamCache.class);
         if (cache != null) {
             cache.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());
@@ -103,23 +109,24 @@ 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());
-        
-        popluateAttachments(request, message);
+
+        populateAttachments(request, message);
     }
-    
-    protected void popluateRequestParameters(HttpServletRequest request, HttpMessage message) {
+
+    protected void populateRequestParameters(HttpServletRequest request, HttpMessage message) {
         //we populate the http request parameters without checking the request method
         Map<String, Object> headers = message.getHeaders();
         Enumeration names = request.getParameterNames();
         while (names.hasMoreElements()) {
-            String name = (String)names.nextElement();
+            String name = (String) names.nextElement();
             Object value = request.getParameter(name);
             if (headerFilterStrategy != null
-                && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, message.getExchange())) {
+                    && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, message.getExchange())) {
                 headers.put(name, value);
             }
         }
-        if (request.getMethod().equals("POST") && request.getContentType() != null && request.getContentType().startsWith("application/x-www-form-urlencoded")) {
+        if (request.getMethod().equals("POST") && request.getContentType() != null
+                && request.getContentType().startsWith(HttpConstants.CONTENT_TYPE_WWW_FORM_URLENCODED)) {
             String charset = request.getCharacterEncoding();
             if (charset == null) {
                 charset = "UTF-8";
@@ -132,7 +139,7 @@ public class DefaultHttpBinding implemen
                     String name = URLDecoder.decode(pair[0], charset);
                     String value = URLDecoder.decode(pair[1], charset);
                     if (headerFilterStrategy != null
-                        && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, message.getExchange())) {
+                            && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, message.getExchange())) {
                         headers.put(name, value);
                     }
                 }
@@ -141,8 +148,8 @@ public class DefaultHttpBinding implemen
             }
         }
     }
-    
-    protected void popluateAttachments(HttpServletRequest request, HttpMessage message) {
+
+    protected void populateAttachments(HttpServletRequest request, HttpMessage message) {
         // check if there is multipart files, if so will put it into DataHandler
         Enumeration names = request.getAttributeNames();
         while (names.hasMoreElements()) {
@@ -150,7 +157,7 @@ public class DefaultHttpBinding implemen
             Object object = request.getAttribute(name);
             if (object instanceof File) {
                 String fileName = request.getParameter(name);
-                message.addAttachment(fileName, new DataHandler(new CamelFileDataSource((File)object, fileName)));
+                message.addAttachment(fileName, new DataHandler(new CamelFileDataSource((File) object, fileName)));
             }
         }
     }
@@ -184,14 +191,22 @@ public class DefaultHttpBinding implemen
     }
 
     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);
-
-        pw.flush();
+        // 500 for internal server error
+        response.setStatus(500);
+        if (endpoint != null && endpoint.isTransferException()) {
+            // transfer the exception as a serialized java object
+            response.setContentType(HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT);
+            ObjectOutputStream oos = new ObjectOutputStream(response.getOutputStream());
+            oos.writeObject(exception);
+            oos.flush();
+            IOHelper.close(oos);
+        } else {
+            // write stacktrace as plain text
+            response.setContentType("text/plain");
+            PrintWriter pw = response.getWriter();
+            exception.printStackTrace(pw);
+            pw.flush();
+        }
     }
 
     public void doWriteFaultResponse(Message message, HttpServletResponse response, Exchange exchange) throws IOException {

Modified: camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpComponent.java?rev=1053033&r1=1053032&r2=1053033&view=diff
==============================================================================
--- camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpComponent.java (original)
+++ camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpComponent.java Mon Dec 27 09:53:44 2010
@@ -147,6 +147,7 @@ public class HttpComponent extends Heade
             binding = resolveAndRemoveReferenceParameter(parameters, "httpBinding", HttpBinding.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 disableStreamCache = getAndRemoveParameter(parameters, "disableStreamCache", Boolean.class);
@@ -158,7 +159,7 @@ public class HttpComponent extends Heade
         URI endpointUri = URISupport.createRemainingURI(new URI(addressUri), CastUtils.cast(httpClientParameters));
         // 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(addressUri), CastUtils.cast(parameters));
-        
+
         // validate http uri that end-user did not duplicate the http part that can be a common error
         String part = httpUri.getSchemeSpecificPart();
         if (part != null) {
@@ -190,6 +191,10 @@ public class HttpComponent extends Heade
         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);
         }

Added: camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpConstants.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpConstants.java?rev=1053033&view=auto
==============================================================================
--- camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpConstants.java (added)
+++ camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpConstants.java Mon Dec 27 09:53:44 2010
@@ -0,0 +1,29 @@
+/**
+ * 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.http4;
+
+/**
+ * @version $Revision$
+ */
+public final class HttpConstants {
+
+    public static final String CONTENT_TYPE_JAVA_SERIALIZED_OBJECT = "application/x-java-serialized-object";
+    public static final String CONTENT_TYPE_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded";
+
+    private HttpConstants() {
+    }
+}

Modified: camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEndpoint.java?rev=1053033&r1=1053032&r2=1053033&view=diff
==============================================================================
--- camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEndpoint.java (original)
+++ camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEndpoint.java Mon Dec 27 09:53:44 2010
@@ -56,6 +56,7 @@ public class HttpEndpoint extends Defaul
     private boolean matchOnUriPrefix;
     private boolean chunked = true;
     private boolean disableStreamCache;
+    private boolean transferException;
 
     public HttpEndpoint() {
     }
@@ -187,7 +188,7 @@ public class HttpEndpoint extends Defaul
 
     public HttpBinding getBinding() {
         if (binding == null) {
-            binding = new DefaultHttpBinding(getHeaderFilterStrategy());
+            binding = new DefaultHttpBinding(this);
         }
         return binding;
     }
@@ -279,4 +280,11 @@ public class HttpEndpoint extends Defaul
         this.chunked = chunked;
     }
 
+    public boolean isTransferException() {
+        return transferException;
+    }
+
+    public void setTransferException(boolean transferException) {
+        this.transferException = transferException;
+    }
 }

Modified: camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpProducer.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpProducer.java?rev=1053033&r1=1053032&r2=1053033&view=diff
==============================================================================
--- camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpProducer.java (original)
+++ camel/trunk/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpProducer.java Mon Dec 27 09:53:44 2010
@@ -19,6 +19,7 @@ package org.apache.camel.component.http4
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.ObjectInputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -60,6 +61,7 @@ public class HttpProducer extends Defaul
     private static final transient Log LOG = LogFactory.getLog(HttpProducer.class);
     private HttpClient httpClient;
     private boolean throwException;
+    private boolean transferException;
 
     public HttpProducer(HttpEndpoint endpoint) {
         super(endpoint);
@@ -68,7 +70,7 @@ 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);
         }
         HttpRequestBase httpRequest = createMethod(exchange);
@@ -87,7 +89,7 @@ public class HttpProducer extends Defaul
                 httpRequest.addHeader(entry.getKey(), headerValue);
             }
         }
-        
+
         // lets store the result in the output message.
         HttpResponse httpResponse = null;
         try {
@@ -121,7 +123,8 @@ public class HttpProducer extends Defaul
         return (HttpEndpoint) super.getEndpoint();
     }
 
-    protected void populateResponse(Exchange exchange, HttpRequestBase httpRequest, HttpResponse httpResponse, Message in, HeaderFilterStrategy strategy, int responseCode) throws IOException {
+    protected void populateResponse(Exchange exchange, HttpRequestBase httpRequest, HttpResponse httpResponse,
+                                    Message in, HeaderFilterStrategy strategy, int responseCode) throws IOException, ClassNotFoundException {
         Message answer = exchange.getOut();
 
         answer.setHeaders(in.getHeaders());
@@ -142,26 +145,33 @@ public class HttpProducer extends Defaul
         }
     }
 
-    protected HttpOperationFailedException populateHttpOperationFailedException(Exchange exchange, HttpRequestBase httpRequest, HttpResponse httpResponse, int responseCode) throws IOException {
-        HttpOperationFailedException exception;
+    protected Exception populateHttpOperationFailedException(Exchange exchange, HttpRequestBase httpRequest, HttpResponse httpResponse, int responseCode) throws IOException, ClassNotFoundException {
+        Exception answer;
+
         String uri = httpRequest.getURI().toString();
         String statusText = httpResponse.getStatusLine() != null ? httpResponse.getStatusLine().getReasonPhrase() : null;
         Map<String, String> headers = extractResponseHeaders(httpResponse.getAllHeaders());
-        InputStream is = extractResponseBody(httpRequest, httpResponse, exchange);
+
+        Object responseBody = extractResponseBody(httpRequest, httpResponse, exchange);
+        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 (is != null) {
-            copy = exchange.getContext().getTypeConverter().convertTo(String.class, exchange, is);
+        if (responseBody != null) {
+            copy = exchange.getContext().getTypeConverter().convertTo(String.class, exchange, responseBody);
         }
 
         Header locationHeader = httpResponse.getFirstHeader("location");
         if (locationHeader != null && (responseCode >= 300 && responseCode < 400)) {
-            exception = new HttpOperationFailedException(uri, responseCode, statusText, locationHeader.getValue(), headers, copy);
+            answer = new HttpOperationFailedException(uri, responseCode, statusText, locationHeader.getValue(), headers, copy);
         } else {
-            exception = new HttpOperationFailedException(uri, responseCode, statusText, null, headers, copy);
+            answer = new HttpOperationFailedException(uri, responseCode, statusText, null, headers, copy);
         }
 
-        return exception;
+        return answer;
     }
 
     /**
@@ -198,10 +208,10 @@ public class HttpProducer extends Defaul
      * Extracts the response from the method as a InputStream.
      *
      * @param httpRequest the method that was executed
-     * @return the response as a stream
+     * @return the response either as a stream, or as a deserialized java object
      * @throws IOException can be thrown
      */
-    protected static InputStream extractResponseBody(HttpRequestBase httpRequest, HttpResponse httpResponse, Exchange exchange) throws IOException {
+    protected static Object extractResponseBody(HttpRequestBase httpRequest, HttpResponse httpResponse, Exchange exchange) throws IOException, ClassNotFoundException {
         HttpEntity entity = httpResponse.getEntity();
         if (entity == null) {
             return null;
@@ -219,16 +229,40 @@ public class HttpProducer extends Defaul
             is = GZIPHelper.uncompressGzip(contentEncoding, is);
         }
         // Honor the character encoding
+        String contentType = null;
         header = httpRequest.getFirstHeader("content-type");
         if (header != null) {
-            String contentType = header.getValue();
+            contentType = header.getValue();
             // find the charset and set it to the Exchange
             HttpHelper.setCharsetFromContentType(contentType, exchange);
         }
-        return doExtractResponseBody(is, exchange);
+        InputStream response = doExtractResponseBodyAsStream(is, exchange);
+        if (contentType != null && contentType.equals(HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT)) {
+            return doDeserializeJavaObjectFromResponse(response);
+        } else {
+            return response;
+        }
     }
 
-    private static InputStream doExtractResponseBody(InputStream is, Exchange exchange) throws IOException {
+    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.
         try {
@@ -248,8 +282,9 @@ public class HttpProducer extends Defaul
      * @param exchange the exchange
      * @return the created method as either GET or POST
      * @throws URISyntaxException is thrown if the URI is invalid
-     * @throws org.apache.camel.InvalidPayloadException is thrown if message body cannot
-     * be converted to a type supported by HttpClient
+     * @throws org.apache.camel.InvalidPayloadException
+     *                            is thrown if message body cannot
+     *                            be converted to a type supported by HttpClient
      */
     protected HttpRequestBase createMethod(Exchange exchange) throws URISyntaxException, InvalidPayloadException {
         String url = HttpProducerHelper.createURL(exchange, getEndpoint());
@@ -298,8 +333,9 @@ public class HttpProducer extends Defaul
      *
      * @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 org.apache.camel.InvalidPayloadException
+     *          is thrown if message body cannot
+     *          be converted to a type supported by HttpClient
      */
     protected HttpEntity createRequestEntity(Exchange exchange) throws InvalidPayloadException {
         Message in = exchange.getIn();
@@ -326,9 +362,9 @@ 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 StringEntity((String)data, charset);
+                        answer = new StringEntity((String) data, charset);
                         if (contentType != null) {
-                            ((StringEntity)answer).setContentType(contentType);
+                            ((StringEntity) answer).setContentType(contentType);
                         }
                     }
 
@@ -338,7 +374,7 @@ public class HttpProducer extends Defaul
                         in.getMandatoryBody(InputStream.class);
                         answer = new InputStreamEntity(in.getBody(InputStream.class), -1);
                         if (contentType != null) {
-                            ((InputStreamEntity)answer).setContentType(contentType);
+                            ((InputStreamEntity) answer).setContentType(contentType);
                         }
                     }
                 }