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 2017/12/18 17:21:01 UTC

[camel] branch master updated: CAMEL-12074: Let okStatusCodeRange support multiple ranges. Thanks to Niels Ull Harremoes for the patch.

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 45b0181  CAMEL-12074: Let okStatusCodeRange support multiple ranges. Thanks to Niels Ull Harremoes for the patch.
45b0181 is described below

commit 45b01813edf3531efcb07ac509e348abb0b772a3
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Dec 18 18:20:45 2017 +0100

    CAMEL-12074: Let okStatusCodeRange support multiple ranges. Thanks to Niels Ull Harremoes for the patch.
---
 .../camel/http/common/HttpCommonEndpoint.java      |   7 +-
 .../org/apache/camel/http/common/HttpHelper.java   |  20 +-
 .../camel-http/src/main/docs/http-component.adoc   |   2 +-
 .../component/http/helper/HttpHelperTest.java      |  26 +++
 .../camel-http4/src/main/docs/http4-component.adoc |   2 +-
 .../component/http4/helper/HttpHelperTest.java     |  28 +++
 .../camel/component/jetty/JettyHttpBinding.java    |   8 +-
 .../src/main/docs/jetty-component.adoc             |   2 +-
 .../src/main/docs/netty-http-component.adoc        |   2 +-
 .../netty/http/NettyHttpConfiguration.java         |   4 +-
 .../component/netty/http/NettyHttpHelper.java      |  20 +-
 .../netty/http/NettyHttpOkStatusCodeTest.java      |  22 ++-
 .../src/main/docs/netty4-http-component.adoc       |   2 +-
 .../netty4/http/NettyHttpConfiguration.java        |   4 +-
 .../component/netty4/http/NettyHttpHelper.java     |  20 +-
 .../netty4/http/NettyHttpOkStatusCodeTest.java     |  23 +++
 .../NettyHttpComponentConfiguration.java           | 205 +++++++++++----------
 .../NettyHttpComponentConfiguration.java           |   7 +-
 18 files changed, 278 insertions(+), 126 deletions(-)

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 23c51c2..58deced 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
@@ -115,7 +115,8 @@ public abstract class HttpCommonEndpoint extends DefaultEndpoint implements Head
             + " Setting this to false will avoid the HTTP Form Encoded body mapping.")
     boolean mapHttpMessageFormUrlEncodedBody = true;
     @UriParam(label = "producer,advanced", defaultValue = "200-299",
-            description = "The status codes which is considered a success response. The values are inclusive. The range must be defined as from-to with the dash included.")
+            description = "The status codes which are considered a success response. The values are inclusive. Multiple ranges can be"
+                    + " defined, separated by comma, e.g. 200-204,209,301-304. Each range must be a single number or from-to with the dash included.")
     private String okStatusCodeRange = "200-299";
     @UriParam(label = "producer,advanced",
             description = "Refers to a custom org.apache.camel.component.http.UrlRewrite which allows you to rewrite urls when you bridge/proxy endpoints."
@@ -487,7 +488,9 @@ public abstract class HttpCommonEndpoint extends DefaultEndpoint implements Head
     }
 
     /**
-     * The status codes which is considered a success response. The values are inclusive. The range must be defined as from-to with the dash included.
+     * The status codes which are considered a success response. The values are inclusive. Multiple ranges can be
+     * defined, separated by comma, e.g. <tt>200-204,209,301-304</tt>. Each range must be a single number or from-to with the
+     * dash included.
      * <p/>
      * The default range is <tt>200-299</tt>
      */
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHelper.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHelper.java
index b03725e..641b0bc 100644
--- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHelper.java
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHelper.java
@@ -40,6 +40,7 @@ import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.util.CamelObjectInputStream;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.URISupport;
 import org.apache.camel.util.UnsafeUriCharactersEncoder;
 import org.slf4j.Logger;
@@ -542,9 +543,22 @@ public final class HttpHelper {
      * @return <tt>true</tt> if ok, <tt>false</tt> otherwise
      */
     public static boolean isStatusCodeOk(int statusCode, String okStatusCodeRange) {
-        int from = Integer.valueOf(ObjectHelper.before(okStatusCodeRange, "-"));
-        int to = Integer.valueOf(ObjectHelper.after(okStatusCodeRange, "-"));
-        return statusCode >= from && statusCode <= to;
+        String[] ranges = okStatusCodeRange.split(",");
+        for (String range : ranges) {
+            boolean ok;
+            if (range.contains("-")) {
+                int from = Integer.valueOf(StringHelper.before(range, "-"));
+                int to = Integer.valueOf(StringHelper.after(range, "-"));
+                ok =  statusCode >= from && statusCode <= to;
+            } else {
+                int exact = Integer.valueOf(range);
+                ok = exact == statusCode;
+            }
+            if (ok) {
+                return true;
+            }
+        }
+        return false;
     }
 
 }
diff --git a/components/camel-http/src/main/docs/http-component.adoc b/components/camel-http/src/main/docs/http-component.adoc
index 0cfa36a..c392bce 100644
--- a/components/camel-http/src/main/docs/http-component.adoc
+++ b/components/camel-http/src/main/docs/http-component.adoc
@@ -175,7 +175,7 @@ with the following path and query parameters:
 | *throwExceptionOnFailure* (producer) | Option to disable throwing the HttpOperationFailedException in case of failed responses from the remote server. This allows you to get all responses regardless of the HTTP status code. | true | boolean
 | *transferException* (producer) | 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 in [...]
 | *cookieHandler* (producer) | Configure a cookie handler to maintain a HTTP session |  | CookieHandler
-| *okStatusCodeRange* (producer) | The status codes which is considered a success response. The values are inclusive. The range must be defined as from-to with the dash included. | 200-299 | String
+| *okStatusCodeRange* (producer) | The status codes which are considered a success response. The values are inclusive. Multiple ranges can be defined separated by comma e.g. 200-204209301-304. Each range must be a single number or from-to with the dash included. | 200-299 | String
 | *urlRewrite* (producer) | *Deprecated* Refers to a custom org.apache.camel.component.http.UrlRewrite which allows you to rewrite urls when you bridge/proxy endpoints. See more details at http://camel.apache.org/urlrewrite.html |  | UrlRewrite
 | *httpClientConfigurer* (advanced) | Register a custom configuration strategy for new HttpClient instances created by producers or consumers such as to configure authentication mechanisms etc |  | HttpClientConfigurer
 | *httpClientOptions* (advanced) | To configure the HttpClient using the key/values from the Map. |  | Map
diff --git a/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpHelperTest.java b/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpHelperTest.java
index 37c39b2..611e0d0 100644
--- a/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpHelperTest.java
+++ b/components/camel-http/src/test/java/org/apache/camel/component/http/helper/HttpHelperTest.java
@@ -33,7 +33,9 @@ import org.apache.camel.impl.DefaultExchange;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 public class HttpHelperTest {
 
@@ -161,6 +163,30 @@ public class HttpHelperTest {
         assertEquals("http://www.google.com/context/search?test=true", url);
     }
 
+    @Test
+    public void testIsStatusCodeOkSimpleRange() throws Exception {
+        assertFalse(HttpHelper.isStatusCodeOk(199, "200-299"));
+        assertTrue(HttpHelper.isStatusCodeOk(200, "200-299"));
+        assertTrue(HttpHelper.isStatusCodeOk(299, "200-299"));
+        assertFalse(HttpHelper.isStatusCodeOk(300, "200-299"));
+        assertFalse(HttpHelper.isStatusCodeOk(300, "301-304"));
+        assertTrue(HttpHelper.isStatusCodeOk(301, "301-304"));
+        assertTrue(HttpHelper.isStatusCodeOk(304, "301-304"));
+        assertFalse(HttpHelper.isStatusCodeOk(305, "301-304"));
+    }
+
+    @Test
+    public void testIsStatusCodeOkComplexRange() throws Exception {
+        assertFalse(HttpHelper.isStatusCodeOk(199, "200-299,404,301-304"));
+        assertTrue(HttpHelper.isStatusCodeOk(200, "200-299,404,301-304"));
+        assertTrue(HttpHelper.isStatusCodeOk(299, "200-299,404,301-304"));
+        assertFalse(HttpHelper.isStatusCodeOk(300, "200-299,404,301-304"));
+        assertTrue(HttpHelper.isStatusCodeOk(301, "200-299,404,301-304"));
+        assertTrue(HttpHelper.isStatusCodeOk(304, "200-299,404,301-304"));
+        assertFalse(HttpHelper.isStatusCodeOk(305, "200-299,404,301-304"));
+        assertTrue(HttpHelper.isStatusCodeOk(404, "200-299,404,301-304"));
+    }
+
     private Exchange createExchangeWithOptionalHttpQueryAndHttpMethodHeader(String httpQuery, HttpMethods httpMethod) {
         CamelContext context = new DefaultCamelContext();
         Exchange exchange = new DefaultExchange(context);
diff --git a/components/camel-http4/src/main/docs/http4-component.adoc b/components/camel-http4/src/main/docs/http4-component.adoc
index a76cd6b..6970507 100644
--- a/components/camel-http4/src/main/docs/http4-component.adoc
+++ b/components/camel-http4/src/main/docs/http4-component.adoc
@@ -124,7 +124,7 @@ with the following path and query parameters:
 | *throwExceptionOnFailure* (producer) | Option to disable throwing the HttpOperationFailedException in case of failed responses from the remote server. This allows you to get all responses regardless of the HTTP status code. | true | boolean
 | *transferException* (producer) | 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 in [...]
 | *cookieHandler* (producer) | Configure a cookie handler to maintain a HTTP session |  | CookieHandler
-| *okStatusCodeRange* (producer) | The status codes which is considered a success response. The values are inclusive. The range must be defined as from-to with the dash included. | 200-299 | String
+| *okStatusCodeRange* (producer) | The status codes which are considered a success response. The values are inclusive. Multiple ranges can be defined separated by comma e.g. 200-204209301-304. Each range must be a single number or from-to with the dash included. | 200-299 | String
 | *urlRewrite* (producer) | *Deprecated* Refers to a custom org.apache.camel.component.http.UrlRewrite which allows you to rewrite urls when you bridge/proxy endpoints. See more details at http://camel.apache.org/urlrewrite.html |  | UrlRewrite
 | *clientBuilder* (advanced) | Provide access to the http client request parameters used on new RequestConfig instances used by producers or consumers of this endpoint. |  | HttpClientBuilder
 | *clientConnectionManager* (advanced) | To use a custom HttpClientConnectionManager to manage connections |  | HttpClientConnection Manager
diff --git a/components/camel-http4/src/test/java/org/apache/camel/component/http4/helper/HttpHelperTest.java b/components/camel-http4/src/test/java/org/apache/camel/component/http4/helper/HttpHelperTest.java
index c067c5b..e8a66fd 100644
--- a/components/camel-http4/src/test/java/org/apache/camel/component/http4/helper/HttpHelperTest.java
+++ b/components/camel-http4/src/test/java/org/apache/camel/component/http4/helper/HttpHelperTest.java
@@ -33,7 +33,10 @@ import org.apache.camel.impl.DefaultExchange;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
 
 public class HttpHelperTest {
 
@@ -184,6 +187,31 @@ public class HttpHelperTest {
         assertEquals("http://www.google.com/context/search?test=true", url);
     }
 
+
+    @Test
+    public void testIsStatusCodeOkSimpleRange() throws Exception {
+        assertFalse(HttpHelper.isStatusCodeOk(199, "200-299"));
+        assertTrue(HttpHelper.isStatusCodeOk(200, "200-299"));
+        assertTrue(HttpHelper.isStatusCodeOk(299, "200-299"));
+        assertFalse(HttpHelper.isStatusCodeOk(300, "200-299"));
+        assertFalse(HttpHelper.isStatusCodeOk(300, "301-304"));
+        assertTrue(HttpHelper.isStatusCodeOk(301, "301-304"));
+        assertTrue(HttpHelper.isStatusCodeOk(304, "301-304"));
+        assertFalse(HttpHelper.isStatusCodeOk(305, "301-304"));
+    }
+
+    @Test
+    public void testIsStatusCodeOkComplexRange() throws Exception {
+        assertFalse(HttpHelper.isStatusCodeOk(199, "200-299,404,301-304"));
+        assertTrue(HttpHelper.isStatusCodeOk(200, "200-299,404,301-304"));
+        assertTrue(HttpHelper.isStatusCodeOk(299, "200-299,404,301-304"));
+        assertFalse(HttpHelper.isStatusCodeOk(300, "200-299,404,301-304"));
+        assertTrue(HttpHelper.isStatusCodeOk(301, "200-299,404,301-304"));
+        assertTrue(HttpHelper.isStatusCodeOk(304, "200-299,404,301-304"));
+        assertFalse(HttpHelper.isStatusCodeOk(305, "200-299,404,301-304"));
+        assertTrue(HttpHelper.isStatusCodeOk(404, "200-299,404,301-304"));
+    }
+
     private Exchange createExchangeWithOptionalHttpQueryAndHttpMethodHeader(String httpQuery, HttpMethods httpMethod) {
         CamelContext context = new DefaultCamelContext();
         Exchange exchange = new DefaultExchange(context);
diff --git a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpBinding.java b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpBinding.java
index a5deb80..9df5c5c 100644
--- a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpBinding.java
+++ b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpBinding.java
@@ -108,14 +108,18 @@ public interface JettyHttpBinding {
     boolean isAllowJavaSerializedObject();
 
     /**
-     * The status codes which is considered a success response. The values are inclusive. The range must be defined as from-to with the dash included.
+     * The status codes which are considered a success response. The values are inclusive. Multiple ranges can be
+     * defined, separated by comma, e.g. <tt>200-204,209,301-304</tt>. Each range must be a single number or from-to
+     * with the dash included.
      * <p/>
      * The default range is <tt>200-299</tt>
      */
     String getOkStatusCodeRange();
 
     /**
-     * The status codes which is considered a success response. The values are inclusive. The range must be defined as from-to with the dash included.
+     * The status codes which are considered a success response. The values are inclusive. Multiple ranges can be
+     * defined, separated by comma, e.g. <tt>200-204,209,301-304</tt>. Each range must be a single number or from-to
+     * with the dash included.
      * <p/>
      * The default range is <tt>200-299</tt>
      */
diff --git a/components/camel-jetty9/src/main/docs/jetty-component.adoc b/components/camel-jetty9/src/main/docs/jetty-component.adoc
index 96ae4fb..60b8c15 100644
--- a/components/camel-jetty9/src/main/docs/jetty-component.adoc
+++ b/components/camel-jetty9/src/main/docs/jetty-component.adoc
@@ -168,7 +168,7 @@ with the following path and query parameters:
 | *httpClientParameters* (producer) | Configuration of Jetty's HttpClient. For example setting httpClient.idleTimeout=30000 sets the idle timeout to 30 seconds. And httpClient.timeout=30000 sets the request timeout to 30 seconds in case you want to timeout sooner if you have long running request/response calls. |  | Map
 | *jettyBinding* (producer) | To use a custom JettyHttpBinding which be used to customize how a response should be written for the producer. |  | JettyHttpBinding
 | *jettyBindingRef* (producer) | *Deprecated* To use a custom JettyHttpBinding which be used to customize how a response should be written for the producer. |  | String
-| *okStatusCodeRange* (producer) | The status codes which is considered a success response. The values are inclusive. The range must be defined as from-to with the dash included. | 200-299 | String
+| *okStatusCodeRange* (producer) | The status codes which are considered a success response. The values are inclusive. Multiple ranges can be defined separated by comma e.g. 200-204209301-304. Each range must be a single number or from-to with the dash included. | 200-299 | String
 | *urlRewrite* (producer) | *Deprecated* Refers to a custom org.apache.camel.component.http.UrlRewrite which allows you to rewrite urls when you bridge/proxy endpoints. See more details at http://camel.apache.org/urlrewrite.html |  | UrlRewrite
 | *mapHttpMessageBody* (advanced) | If this option is true then IN exchange Body of the exchange will be mapped to HTTP body. Setting this to false will avoid the HTTP mapping. | true | boolean
 | *mapHttpMessageFormUrl EncodedBody* (advanced) | If this option is true then IN exchange Form Encoded body of the exchange will be mapped to HTTP. Setting this to false will avoid the HTTP Form Encoded body mapping. | true | boolean
diff --git a/components/camel-netty-http/src/main/docs/netty-http-component.adoc b/components/camel-netty-http/src/main/docs/netty-http-component.adoc
index 88bcf70..40ca3ba 100644
--- a/components/camel-netty-http/src/main/docs/netty-http-component.adoc
+++ b/components/camel-netty-http/src/main/docs/netty-http-component.adoc
@@ -165,7 +165,7 @@ with the following path and query parameters:
 | *throwExceptionOnFailure* (producer) | Option to disable throwing the HttpOperationFailedException in case of failed responses from the remote server. This allows you to get all responses regardless of the HTTP status code. | true | boolean
 | *clientPipelineFactory* (producer) | To use a custom ClientPipelineFactory |  | ClientPipelineFactory
 | *lazyChannelCreation* (producer) | Channels can be lazily created to avoid exceptions if the remote server is not up and running when the Camel producer is started. | true | boolean
-| *okStatusCodeRange* (producer) | The status codes which is considered a success response. The values are inclusive. The range must be defined as from-to with the dash included. The default range is 200-299 | 200-299 | String
+| *okStatusCodeRange* (producer) | The status codes which are considered a success response. The values are inclusive. Multiple ranges can be defined separated by comma e.g. 200-204209301-304. Each range must be a single number or from-to with the dash included. The default range is 200-299 | 200-299 | String
 | *producerPoolEnabled* (producer) | Whether producer pool is enabled or not. Important: Do not turn this off as the pooling is needed for handling concurrency and reliable request/reply. | true | boolean
 | *producerPoolMaxActive* (producer) | Sets the cap on the number of objects that can be allocated by the pool (checked out to clients or idle awaiting checkout) at a given time. Use a negative value for no limit. | -1 | int
 | *producerPoolMaxIdle* (producer) | Sets the cap on the number of idle instances in the pool. | 100 | int
diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConfiguration.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConfiguration.java
index 3cd223d..284d717b 100644
--- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConfiguration.java
+++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConfiguration.java
@@ -305,7 +305,9 @@ public class NettyHttpConfiguration extends NettyConfiguration {
     }
 
     /**
-     * The status codes which is considered a success response. The values are inclusive. The range must be defined as from-to with the dash included.
+     * The status codes which are considered a success response. The values are inclusive. Multiple ranges can be
+     * defined, separated by comma, e.g. <tt>200-204,209,301-304</tt>. Each range must be a single number or from-to with the
+     * dash included.
      * <p/>
      * The default range is <tt>200-299</tt>
      */
diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java
index cea0b0a4..a04f79d 100644
--- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java
+++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java
@@ -31,6 +31,7 @@ import org.apache.camel.RuntimeExchangeException;
 import org.apache.camel.converter.IOConverter;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.URISupport;
 import org.apache.camel.util.UnsafeUriCharactersEncoder;
 import org.jboss.netty.handler.codec.http.HttpMethod;
@@ -262,9 +263,22 @@ public final class NettyHttpHelper {
      * @return <tt>true</tt> if ok, <tt>false</tt> otherwise
      */
     public static boolean isStatusCodeOk(int statusCode, String okStatusCodeRange) {
-        int from = Integer.valueOf(ObjectHelper.before(okStatusCodeRange, "-"));
-        int to = Integer.valueOf(ObjectHelper.after(okStatusCodeRange, "-"));
-        return statusCode >= from && statusCode <= to;
+        String[] ranges = okStatusCodeRange.split(",");
+        for (String range : ranges) {
+            boolean ok;
+            if (range.contains("-")) {
+                int from = Integer.valueOf(StringHelper.before(range, "-"));
+                int to = Integer.valueOf(StringHelper.after(range, "-"));
+                ok =  statusCode >= from && statusCode <= to;
+            } else {
+                int exact = Integer.valueOf(range);
+                ok = exact == statusCode;
+            }
+            if (ok) {
+                return true;
+            }
+        }
+        return false;
     }
 
 }
diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpOkStatusCodeTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpOkStatusCodeTest.java
index d474651..c42c75e 100644
--- a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpOkStatusCodeTest.java
+++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpOkStatusCodeTest.java
@@ -38,9 +38,29 @@ public class NettyHttpOkStatusCodeTest extends BaseNettyTest {
     }
 
     @Test
+    public void testNoOkComplexRange() throws Exception {
+        byte[] data = "Hello World".getBytes();
+        try {
+            template.requestBody("netty-http:http://localhost:{{port}}/test?okStatusCodeRange=200-204,301", data, String.class);
+            fail("Should have thrown exception");
+        } catch (CamelExecutionException e) {
+            NettyHttpOperationFailedException cause = assertIsInstanceOf(NettyHttpOperationFailedException.class, e.getCause());
+            assertEquals(209, cause.getStatusCode());
+            String body = context.getTypeConverter().convertTo(String.class, cause.getResponse().getContent());
+            assertEquals("Not allowed", body);
+        }
+    }
+
+    @Test
     public void testOk() throws Exception {
         byte[] data = "Hello World".getBytes();
-        String out = template.requestBody("netty-http:http://localhost:{{port}}/test?okStatusCodeRange=200-209", data, String.class);
+        String out = template.requestBody("netty-http:http://localhost:{{port}}/test?okStatusCodeRange=200-204,209,301-304", data, String.class);
+        assertEquals("Not allowed", out);
+    }
+    @Test
+    public void testOkComplexRange() throws Exception {
+        byte[] data = "Hello World".getBytes();
+        String out = template.requestBody("netty-http:http://localhost:{{port}}/test?okStatusCodeRange=200-204,209,301-304", data, String.class);
         assertEquals("Not allowed", out);
     }
 
diff --git a/components/camel-netty4-http/src/main/docs/netty4-http-component.adoc b/components/camel-netty4-http/src/main/docs/netty4-http-component.adoc
index 33cfa58..fd8956c 100644
--- a/components/camel-netty4-http/src/main/docs/netty4-http-component.adoc
+++ b/components/camel-netty4-http/src/main/docs/netty4-http-component.adoc
@@ -163,7 +163,7 @@ with the following path and query parameters:
 | *throwExceptionOnFailure* (producer) | Option to disable throwing the HttpOperationFailedException in case of failed responses from the remote server. This allows you to get all responses regardless of the HTTP status code. | true | boolean
 | *clientInitializerFactory* (producer) | To use a custom ClientInitializerFactory |  | ClientInitializer Factory
 | *lazyChannelCreation* (producer) | Channels can be lazily created to avoid exceptions if the remote server is not up and running when the Camel producer is started. | true | boolean
-| *okStatusCodeRange* (producer) | The status codes which is considered a success response. The values are inclusive. The range must be defined as from-to with the dash included. The default range is 200-299 | 200-299 | String
+| *okStatusCodeRange* (producer) | The status codes which are considered a success response. The values are inclusive. Multiple ranges can be defined separated by comma e.g. 200-204209301-304. Each range must be a single number or from-to with the dash included. The default range is 200-299 | 200-299 | String
 | *producerPoolEnabled* (producer) | Whether producer pool is enabled or not. Important: Do not turn this off as the pooling is needed for handling concurrency and reliable request/reply. | true | boolean
 | *producerPoolMaxActive* (producer) | Sets the cap on the number of objects that can be allocated by the pool (checked out to clients or idle awaiting checkout) at a given time. Use a negative value for no limit. | -1 | int
 | *producerPoolMaxIdle* (producer) | Sets the cap on the number of idle instances in the pool. | 100 | int
diff --git a/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpConfiguration.java b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpConfiguration.java
index 8202418..75f51f1 100644
--- a/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpConfiguration.java
+++ b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpConfiguration.java
@@ -307,7 +307,9 @@ public class NettyHttpConfiguration extends NettyConfiguration {
     }
 
     /**
-     * The status codes which is considered a success response. The values are inclusive. The range must be defined as from-to with the dash included.
+     * The status codes which are considered a success response. The values are inclusive. Multiple ranges can be
+     * defined, separated by comma, e.g. <tt>200-204,209,301-304</tt>. Each range must be a single number or from-to with the
+     * dash included.
      * <p/>
      * The default range is <tt>200-299</tt>
      */
diff --git a/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpHelper.java b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpHelper.java
index 937cc9c..d165c89 100644
--- a/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpHelper.java
+++ b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpHelper.java
@@ -33,6 +33,7 @@ import org.apache.camel.RuntimeExchangeException;
 import org.apache.camel.converter.IOConverter;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.URISupport;
 import org.apache.camel.util.UnsafeUriCharactersEncoder;
 
@@ -273,9 +274,22 @@ public final class NettyHttpHelper {
      * @return <tt>true</tt> if ok, <tt>false</tt> otherwise
      */
     public static boolean isStatusCodeOk(int statusCode, String okStatusCodeRange) {
-        int from = Integer.valueOf(ObjectHelper.before(okStatusCodeRange, "-"));
-        int to = Integer.valueOf(ObjectHelper.after(okStatusCodeRange, "-"));
-        return statusCode >= from && statusCode <= to;
+        String[] ranges = okStatusCodeRange.split(",");
+        for (String range : ranges) {
+            boolean ok;
+            if (range.contains("-")) {
+                int from = Integer.valueOf(StringHelper.before(range, "-"));
+                int to = Integer.valueOf(StringHelper.after(range, "-"));
+                ok =  statusCode >= from && statusCode <= to;
+            } else {
+                int exact = Integer.valueOf(range);
+                ok = exact == statusCode;
+            }
+            if (ok) {
+                return true;
+            }
+        }
+        return false;
     }
 
 }
diff --git a/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpOkStatusCodeTest.java b/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpOkStatusCodeTest.java
index 3aef7f3..eb2fd50 100644
--- a/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpOkStatusCodeTest.java
+++ b/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/NettyHttpOkStatusCodeTest.java
@@ -37,6 +37,21 @@ public class NettyHttpOkStatusCodeTest extends BaseNettyTest {
         }
     }
 
+
+    @Test
+    public void testNoOkComplexRange() throws Exception {
+        byte[] data = "Hello World".getBytes();
+        try {
+            template.requestBody("netty4-http:http://localhost:{{port}}/test?okStatusCodeRange=200-204,301", data, String.class);
+            fail("Should have thrown exception");
+        } catch (CamelExecutionException e) {
+            NettyHttpOperationFailedException cause = assertIsInstanceOf(NettyHttpOperationFailedException.class, e.getCause());
+            assertEquals(209, cause.getStatusCode());
+            String body = cause.getContentAsString();
+            assertEquals("Not allowed", body);
+        }
+    }
+
     @Test
     public void testOk() throws Exception {
         byte[] data = "Hello World".getBytes();
@@ -44,6 +59,14 @@ public class NettyHttpOkStatusCodeTest extends BaseNettyTest {
         assertEquals("Not allowed", out);
     }
 
+
+    @Test
+    public void testOkComplexRange() throws Exception {
+        byte[] data = "Hello World".getBytes();
+        String out = template.requestBody("netty4-http:http://localhost:{{port}}/test?okStatusCodeRange=200-204,209,301-304", data, String.class);
+        assertEquals("Not allowed", out);
+    }
+
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
diff --git a/platforms/spring-boot/components-starter/camel-netty-http-starter/src/main/java/org/apache/camel/component/netty/http/springboot/NettyHttpComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-netty-http-starter/src/main/java/org/apache/camel/component/netty/http/springboot/NettyHttpComponentConfiguration.java
index 32613f4..06ca015 100644
--- a/platforms/spring-boot/components-starter/camel-netty-http-starter/src/main/java/org/apache/camel/component/netty/http/springboot/NettyHttpComponentConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-netty-http-starter/src/main/java/org/apache/camel/component/netty/http/springboot/NettyHttpComponentConfiguration.java
@@ -136,6 +136,105 @@ public class NettyHttpComponentConfiguration
         this.resolvePropertyPlaceholders = resolvePropertyPlaceholders;
     }
 
+    public static class NettyHttpSecurityConfigurationNestedConfiguration {
+        public static final Class CAMEL_NESTED_CLASS = org.apache.camel.component.netty.http.NettyHttpSecurityConfiguration.class;
+        /**
+         * Whether to enable authentication
+         * <p/>
+         * This is by default enabled.
+         */
+        private Boolean authenticate;
+        /**
+         * The supported restricted.
+         * <p/>
+         * Currently only Basic is supported.
+         */
+        private String constraint;
+        /**
+         * Sets the name of the realm to use.
+         */
+        private String realm;
+        /**
+         * Sets a {@link SecurityConstraint} to use for checking if a web
+         * resource is restricted or not
+         * <p/>
+         * By default this is <tt>null</tt>, which means all resources is
+         * restricted.
+         */
+        private SecurityConstraint securityConstraint;
+        /**
+         * Sets the {@link SecurityAuthenticator} to use for authenticating the
+         * {@link HttpPrincipal} .
+         */
+        private SecurityAuthenticator securityAuthenticator;
+        /**
+         * Sets a logging level to use for logging denied login attempts (incl
+         * stacktraces)
+         * <p/>
+         * This level is by default DEBUG.
+         */
+        private LoggingLevel loginDeniedLoggingLevel;
+        private String roleClassName;
+
+        public Boolean getAuthenticate() {
+            return authenticate;
+        }
+
+        public void setAuthenticate(Boolean authenticate) {
+            this.authenticate = authenticate;
+        }
+
+        public String getConstraint() {
+            return constraint;
+        }
+
+        public void setConstraint(String constraint) {
+            this.constraint = constraint;
+        }
+
+        public String getRealm() {
+            return realm;
+        }
+
+        public void setRealm(String realm) {
+            this.realm = realm;
+        }
+
+        public SecurityConstraint getSecurityConstraint() {
+            return securityConstraint;
+        }
+
+        public void setSecurityConstraint(SecurityConstraint securityConstraint) {
+            this.securityConstraint = securityConstraint;
+        }
+
+        public SecurityAuthenticator getSecurityAuthenticator() {
+            return securityAuthenticator;
+        }
+
+        public void setSecurityAuthenticator(
+                SecurityAuthenticator securityAuthenticator) {
+            this.securityAuthenticator = securityAuthenticator;
+        }
+
+        public LoggingLevel getLoginDeniedLoggingLevel() {
+            return loginDeniedLoggingLevel;
+        }
+
+        public void setLoginDeniedLoggingLevel(
+                LoggingLevel loginDeniedLoggingLevel) {
+            this.loginDeniedLoggingLevel = loginDeniedLoggingLevel;
+        }
+
+        public String getRoleClassName() {
+            return roleClassName;
+        }
+
+        public void setRoleClassName(String roleClassName) {
+            this.roleClassName = roleClassName;
+        }
+    }
+
     public static class NettyHttpConfigurationNestedConfiguration {
         public static final Class CAMEL_NESTED_CLASS = org.apache.camel.component.netty.http.NettyHttpConfiguration.class;
         /**
@@ -247,9 +346,10 @@ public class NettyHttpComponentConfiguration
         private Integer maxHeaderSize = 8192;
         private Boolean allowDefaultCodec;
         /**
-         * The status codes which is considered a success response. The values
-         * are inclusive. The range must be defined as from-to with the dash
-         * included.
+         * The status codes which are considered a success response. The values
+         * are inclusive. Multiple ranges can be defined, separated by comma,
+         * e.g. <tt>200-204,209,301-304</tt>. Each range must be a single number
+         * or from-to with the dash included.
          * <p/>
          * The default range is <tt>200-299</tt>
          */
@@ -407,103 +507,4 @@ public class NettyHttpComponentConfiguration
             this.useRelativePath = useRelativePath;
         }
     }
-
-    public static class NettyHttpSecurityConfigurationNestedConfiguration {
-        public static final Class CAMEL_NESTED_CLASS = org.apache.camel.component.netty.http.NettyHttpSecurityConfiguration.class;
-        /**
-         * Whether to enable authentication
-         * <p/>
-         * This is by default enabled.
-         */
-        private Boolean authenticate;
-        /**
-         * The supported restricted.
-         * <p/>
-         * Currently only Basic is supported.
-         */
-        private String constraint;
-        /**
-         * Sets the name of the realm to use.
-         */
-        private String realm;
-        /**
-         * Sets a {@link SecurityConstraint} to use for checking if a web
-         * resource is restricted or not
-         * <p/>
-         * By default this is <tt>null</tt>, which means all resources is
-         * restricted.
-         */
-        private SecurityConstraint securityConstraint;
-        /**
-         * Sets the {@link SecurityAuthenticator} to use for authenticating the
-         * {@link HttpPrincipal} .
-         */
-        private SecurityAuthenticator securityAuthenticator;
-        /**
-         * Sets a logging level to use for logging denied login attempts (incl
-         * stacktraces)
-         * <p/>
-         * This level is by default DEBUG.
-         */
-        private LoggingLevel loginDeniedLoggingLevel;
-        private String roleClassName;
-
-        public Boolean getAuthenticate() {
-            return authenticate;
-        }
-
-        public void setAuthenticate(Boolean authenticate) {
-            this.authenticate = authenticate;
-        }
-
-        public String getConstraint() {
-            return constraint;
-        }
-
-        public void setConstraint(String constraint) {
-            this.constraint = constraint;
-        }
-
-        public String getRealm() {
-            return realm;
-        }
-
-        public void setRealm(String realm) {
-            this.realm = realm;
-        }
-
-        public SecurityConstraint getSecurityConstraint() {
-            return securityConstraint;
-        }
-
-        public void setSecurityConstraint(SecurityConstraint securityConstraint) {
-            this.securityConstraint = securityConstraint;
-        }
-
-        public SecurityAuthenticator getSecurityAuthenticator() {
-            return securityAuthenticator;
-        }
-
-        public void setSecurityAuthenticator(
-                SecurityAuthenticator securityAuthenticator) {
-            this.securityAuthenticator = securityAuthenticator;
-        }
-
-        public LoggingLevel getLoginDeniedLoggingLevel() {
-            return loginDeniedLoggingLevel;
-        }
-
-        public void setLoginDeniedLoggingLevel(
-                LoggingLevel loginDeniedLoggingLevel) {
-            this.loginDeniedLoggingLevel = loginDeniedLoggingLevel;
-        }
-
-        public String getRoleClassName() {
-            return roleClassName;
-        }
-
-        public void setRoleClassName(String roleClassName) {
-            this.roleClassName = roleClassName;
-        }
-    }
 }
\ No newline at end of file
diff --git a/platforms/spring-boot/components-starter/camel-netty4-http-starter/src/main/java/org/apache/camel/component/netty4/http/springboot/NettyHttpComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-netty4-http-starter/src/main/java/org/apache/camel/component/netty4/http/springboot/NettyHttpComponentConfiguration.java
index f0141c5..bfbf027 100644
--- a/platforms/spring-boot/components-starter/camel-netty4-http-starter/src/main/java/org/apache/camel/component/netty4/http/springboot/NettyHttpComponentConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-netty4-http-starter/src/main/java/org/apache/camel/component/netty4/http/springboot/NettyHttpComponentConfiguration.java
@@ -266,9 +266,10 @@ public class NettyHttpComponentConfiguration
         private Integer maxHeaderSize = 8192;
         private Boolean allowDefaultCodec;
         /**
-         * The status codes which is considered a success response. The values
-         * are inclusive. The range must be defined as from-to with the dash
-         * included.
+         * The status codes which are considered a success response. The values
+         * are inclusive. Multiple ranges can be defined, separated by comma,
+         * e.g. <tt>200-204,209,301-304</tt>. Each range must be a single number
+         * or from-to with the dash included.
          * <p/>
          * The default range is <tt>200-299</tt>
          */

-- 
To stop receiving notification emails like this one, please contact
['"commits@camel.apache.org" <co...@camel.apache.org>'].