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 2019/10/16 03:58:03 UTC

[camel] branch master updated: CAMEL-14025: add muteException option to camel-servlet component (#3251)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 891e8b1  CAMEL-14025: add muteException option to camel-servlet component (#3251)
891e8b1 is described below

commit 891e8b17865f1906f163080427520357bc9e4f63
Author: mschnitzler <sc...@gmail.com>
AuthorDate: Wed Oct 16 05:57:52 2019 +0200

    CAMEL-14025: add muteException option to camel-servlet component (#3251)
---
 .../camel/http/common/DefaultHttpBinding.java      | 16 +++++
 .../org/apache/camel/http/common/HttpBinding.java  | 10 ++++
 .../camel/http/common/HttpCommonEndpoint.java      | 13 ++++
 .../src/main/docs/servlet-component.adoc           |  3 +-
 .../camel/component/servlet/ServletComponent.java  |  5 ++
 .../camel/component/servlet/ServletEndpoint.java   |  1 +
 .../servlet/ServletMuteExceptionTest.java          | 70 ++++++++++++++++++++++
 7 files changed, 117 insertions(+), 1 deletion(-)

diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
index a8d8bdc..5bdcc36 100644
--- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
@@ -79,6 +79,7 @@ public class DefaultHttpBinding implements HttpBinding {
     private boolean useReaderForPayload;
     private boolean eagerCheckContentAvailable;
     private boolean transferException;
+    private boolean muteException;
     private boolean allowJavaSerializedObject;
     private boolean mapHttpMessageBody = true;
     private boolean mapHttpMessageHeaders = true;
@@ -98,6 +99,7 @@ public class DefaultHttpBinding implements HttpBinding {
     public DefaultHttpBinding(HttpCommonEndpoint endpoint) {
         this.headerFilterStrategy = endpoint.getHeaderFilterStrategy();
         this.transferException = endpoint.isTransferException();
+        this.muteException = endpoint.isMuteException();
         if (endpoint.getComponent() != null) {
             this.allowJavaSerializedObject = endpoint.getComponent().isAllowJavaSerializedObject();
         }
@@ -362,6 +364,10 @@ public class DefaultHttpBinding implements HttpBinding {
             response.setStatus(HttpServletResponse.SC_GATEWAY_TIMEOUT);
             response.setContentType("text/plain");
             response.getWriter().write("Timeout error");
+        } else if (isMuteException()) {
+            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            response.setContentType("text/plain");
+            response.getWriter().write("Exception");
         } else {
             response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
 
@@ -636,6 +642,16 @@ public class DefaultHttpBinding implements HttpBinding {
     }
 
     @Override
+    public boolean isMuteException() {
+        return muteException;
+    }
+
+    @Override
+    public void setMuteException(boolean muteException) {
+        this.muteException = muteException;
+    }
+
+    @Override
     public boolean isAllowJavaSerializedObject() {
         return allowJavaSerializedObject;
     }
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpBinding.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpBinding.java
index 2f91e8c..70f5f80 100644
--- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpBinding.java
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpBinding.java
@@ -125,6 +125,11 @@ public interface HttpBinding {
     boolean isTransferException();
 
     /**
+     * If enabled and an Exchange failed processing on the consumer side the response's body won't contain the exception's stack trace.
+     */
+    boolean isMuteException();
+
+    /**
      * Whether to allow java serialization when a request uses context-type=application/x-java-serialized-object
      * <p/>
      * This is by default turned off. If you enable this then be aware that Java will deserialize the incoming
@@ -171,6 +176,11 @@ public interface HttpBinding {
     void setTransferException(boolean transferException);
 
     /**
+     * If enabled and an Exchange failed processing on the consumer side the response's body won't contain the exception's stack trace.
+     */
+    void setMuteException(boolean muteException);
+
+    /**
      * Whether to allow java serialization when a request uses context-type=application/x-java-serialized-object
      * <p/>
      * This is by default turned off. If you enable this then be aware that Java will deserialize the incoming
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
index 547ec36..d36c728 100644
--- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
@@ -81,6 +81,9 @@ public abstract class HttpCommonEndpoint extends DefaultEndpoint implements Head
             + " This is by default turned off. If you enable this then be aware that Java will deserialize the incoming"
             + " data from the request to Java and that can be a potential security risk.")
     boolean transferException;
+    @UriParam(label="consumer",
+            description = "If enabled and an Exchange failed processing on the consumer side the response's body won't contain the exception's stack trace.")
+    boolean muteException;
     @UriParam(label = "producer", defaultValue = "false", description = "Specifies whether a Connection Close header must be added to HTTP Request. By default connectionClose is false.")
     boolean connectionClose;
     @UriParam(label = "consumer,advanced",
@@ -230,6 +233,7 @@ public abstract class HttpCommonEndpoint extends DefaultEndpoint implements Head
             httpBinding = new DefaultHttpBinding();
             httpBinding.setHeaderFilterStrategy(getHeaderFilterStrategy());
             httpBinding.setTransferException(isTransferException());
+            httpBinding.setMuteException(isMuteException());
             if (getComponent() != null) {
                 httpBinding.setAllowJavaSerializedObject(getComponent().isAllowJavaSerializedObject());
             }
@@ -377,6 +381,10 @@ public abstract class HttpCommonEndpoint extends DefaultEndpoint implements Head
     public boolean isTransferException() {
         return transferException;
     }
+
+    public boolean isMuteException() {
+        return muteException;
+    }
     
     public boolean isConnectionClose() {
         return connectionClose;
@@ -402,6 +410,11 @@ public abstract class HttpCommonEndpoint extends DefaultEndpoint implements Head
         this.transferException = transferException;
     }
 
+    /**
+     * If enabled and an Exchange failed processing on the consumer side the response's body won't contain the exception's stack trace.
+     */
+    public void setMuteException(boolean muteException) { this.muteException = muteException; }
+
     public boolean isTraceEnabled() {
         return this.traceEnabled;
     }
diff --git a/components/camel-servlet/src/main/docs/servlet-component.adoc b/components/camel-servlet/src/main/docs/servlet-component.adoc
index 5d1252e..4eec06f 100644
--- a/components/camel-servlet/src/main/docs/servlet-component.adoc
+++ b/components/camel-servlet/src/main/docs/servlet-component.adoc
@@ -85,7 +85,7 @@ with the following path and query parameters:
 |===
 
 
-=== Query Parameters (23 parameters):
+=== Query Parameters (24 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -99,6 +99,7 @@ with the following path and query parameters:
 | *chunked* (consumer) | If this option is false the Servlet will disable the HTTP streaming and set the content-length header on the response | true | boolean
 | *httpMethodRestrict* (consumer) | Used to only allow consuming if the HttpMethod matches, such as GET/POST/PUT etc. Multiple methods can be specified separated by comma. |  | String
 | *matchOnUriPrefix* (consumer) | Whether or not the consumer should try to find a target consumer by matching the URI prefix if no exact match is found. | false | boolean
+| *muteException* (consumer) | If enabled and an Exchange failed processing on the consumer side the response's body won't contain the exception's stack trace. | false | boolean
 | *responseBufferSize* (consumer) | To use a custom buffer size on the javax.servlet.ServletResponse. |  | Integer
 | *servletName* (consumer) | Name of the servlet to use | CamelServlet | String
 | *transferException* (consumer) | If enabled and an Exchange failed processing on the consumer side, and if the caused Exception was send back serialized in the response as a application/x-java-serialized-object content type. On the producer side the exception will be deserialized and thrown as is, instead of the HttpOperationFailedException. The caused exception is required to be serialized. This is by default turned off. If you enable this then be aware that Java will deserialize the  [...]
diff --git a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java
index b4c35fb..48aa2ec 100644
--- a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java
+++ b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java
@@ -68,6 +68,7 @@ public class ServletComponent extends HttpCommonComponent implements RestConsume
         // 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 muteException = getAndRemoveParameter(parameters, "muteException", Boolean.class);
         Boolean bridgeEndpoint = getAndRemoveParameter(parameters, "bridgeEndpoint", Boolean.class);
         HttpBinding binding = resolveAndRemoveReferenceParameter(parameters, "httpBinding", HttpBinding.class);
         Boolean matchOnUriPrefix = getAndRemoveParameter(parameters, "matchOnUriPrefix", Boolean.class);
@@ -122,6 +123,9 @@ public class ServletComponent extends HttpCommonComponent implements RestConsume
         if (transferException != null) {
             endpoint.setTransferException(transferException);
         }
+        if (muteException != null) {
+            endpoint.setMuteException(muteException);
+        }
         if (bridgeEndpoint != null) {
             endpoint.setBridgeEndpoint(bridgeEndpoint);
         }
@@ -322,6 +326,7 @@ public class ServletComponent extends HttpCommonComponent implements RestConsume
             HttpBinding binding = new ServletRestHttpBinding();
             binding.setHeaderFilterStrategy(endpoint.getHeaderFilterStrategy());
             binding.setTransferException(endpoint.isTransferException());
+            binding.setMuteException(endpoint.isMuteException());
             binding.setEagerCheckContentAvailable(endpoint.isEagerCheckContentAvailable());
             endpoint.setHttpBinding(binding);
         }
diff --git a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletEndpoint.java b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletEndpoint.java
index 482f5f4..a0596df 100644
--- a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletEndpoint.java
+++ b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletEndpoint.java
@@ -74,6 +74,7 @@ public class ServletEndpoint extends HttpCommonEndpoint {
             }
             this.binding.setFileNameExtWhitelist(getFileNameExtWhitelist());
             this.binding.setTransferException(isTransferException());
+            this.binding.setMuteException(isMuteException());
             if (getComponent() != null) {
                 this.binding.setAllowJavaSerializedObject(getComponent().isAllowJavaSerializedObject());
             }
diff --git a/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletMuteExceptionTest.java b/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletMuteExceptionTest.java
new file mode 100644
index 0000000..92dbb3e
--- /dev/null
+++ b/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/ServletMuteExceptionTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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 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.http.common.HttpConstants;
+import org.apache.camel.http.common.HttpHelper;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+
+public class ServletMuteExceptionTest extends ServletCamelRouterTestSupport {
+
+    @Test
+    public void testMuteException() throws Exception {
+        WebRequest req = new PostMethodWebRequest(CONTEXT_URL + "/services/mute", new ByteArrayInputStream("".getBytes()), "text/plain");
+        ServletUnitClient client = newClient();
+        client.setExceptionsThrownOnErrorStatus(false);
+        WebResponse response = client.getResponse(req);
+
+        assertEquals(500, response.getResponseCode());
+        assertEquals("text/plain", response.getContentType());
+        assertEquals("Exception", response.getText());
+    }
+
+
+    @Test
+    public void testMuteWithTransferException() throws Exception {
+        WebRequest req = new PostMethodWebRequest(CONTEXT_URL + "/services/muteWithTransfer", new ByteArrayInputStream("".getBytes()), "text/plain");
+        ServletUnitClient client = newClient();
+        client.setExceptionsThrownOnErrorStatus(false);
+        WebResponse response = client.getResponse(req);
+
+        assertEquals(500, response.getResponseCode());
+        assertEquals("text/plain", response.getContentType());
+        assertEquals("Exception", response.getText());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("servlet:mute?muteException=true")
+                    .throwException(new IllegalArgumentException("Damn"));
+
+                from("servlet:muteWithTransfer?muteException=true&transferException=true")
+                    .throwException(new IllegalArgumentException("Damn"));
+            }
+        };
+    }
+}