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 2018/08/27 14:08:48 UTC

[camel] 01/03: CAMEL-12753: Fixed camel-undertow consumer with OPTIONS in rest-dsl to return mutiple verbs if the same context-path has more http verbs like GET, POST etc. Thanks to Tomas Turek for unit test

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

commit c3cd89585c4a437767a8e72aee388f3ed17c62e9
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Aug 27 14:58:57 2018 +0200

    CAMEL-12753: Fixed camel-undertow consumer with OPTIONS in rest-dsl to return mutiple verbs if the same context-path has more http verbs like GET,POST etc. Thanks to Tomas Turek for unit test
---
 .../undertow/HttpHandlerRegistrationInfo.java      | 20 +++++++++++++
 .../component/undertow/UndertowComponent.java      | 13 +++++++--
 .../camel/component/undertow/UndertowConsumer.java | 33 ++++++++++++++++++----
 .../undertow/rest/RestUndertowHttpOptionsTest.java | 19 ++++++++++++-
 4 files changed, 75 insertions(+), 10 deletions(-)

diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/HttpHandlerRegistrationInfo.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/HttpHandlerRegistrationInfo.java
index ce93093..9e55856 100644
--- a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/HttpHandlerRegistrationInfo.java
+++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/HttpHandlerRegistrationInfo.java
@@ -17,6 +17,7 @@
 package org.apache.camel.component.undertow;
 
 import java.net.URI;
+import java.util.Objects;
 
 public class HttpHandlerRegistrationInfo {
 
@@ -48,4 +49,23 @@ public class HttpHandlerRegistrationInfo {
         return uri + "?matchOnUriPrefix=" + matchOnUriPrefix + "&methodRestrict=" + methodRestrict;
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        HttpHandlerRegistrationInfo that = (HttpHandlerRegistrationInfo) o;
+        return Objects.equals(matchOnUriPrefix, that.matchOnUriPrefix)
+            && Objects.equals(methodRestrict, that.methodRestrict)
+            && Objects.equals(uri, that.uri);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(matchOnUriPrefix, methodRestrict, uri);
+    }
+
 }
diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java
index 62014cd..4857b59 100644
--- a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java
+++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java
@@ -19,14 +19,14 @@ package org.apache.camel.component.undertow;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
-
 import javax.net.ssl.SSLContext;
 
 import io.undertow.server.HttpHandler;
-
 import org.apache.camel.CamelContext;
 import org.apache.camel.ComponentVerifier;
 import org.apache.camel.Consumer;
@@ -61,7 +61,8 @@ import org.slf4j.LoggerFactory;
 public class UndertowComponent extends DefaultComponent implements RestConsumerFactory, RestApiConsumerFactory, RestProducerFactory, VerifiableComponent, SSLContextParametersAware {
     private static final Logger LOG = LoggerFactory.getLogger(UndertowEndpoint.class);
 
-    private Map<UndertowHostKey, UndertowHost> undertowRegistry = new ConcurrentHashMap<>();
+    private final Map<UndertowHostKey, UndertowHost> undertowRegistry = new ConcurrentHashMap<>();
+    private final Set<HttpHandlerRegistrationInfo> handlers = new HashSet<>();
 
     @Metadata(label = "advanced")
     private UndertowHttpBinding undertowHttpBinding;
@@ -332,6 +333,7 @@ public class UndertowComponent extends DefaultComponent implements RestConsumerF
         final UndertowHost host = undertowRegistry.computeIfAbsent(key, k -> createUndertowHost(k));
 
         host.validateEndpointURI(uri);
+        handlers.add(registrationInfo);
         return host.registerHandler(registrationInfo, handler);
     }
 
@@ -339,6 +341,7 @@ public class UndertowComponent extends DefaultComponent implements RestConsumerF
         final URI uri = registrationInfo.getUri();
         final UndertowHostKey key = new UndertowHostKey(uri.getHost(), uri.getPort(), sslContext);
         final UndertowHost host = undertowRegistry.get(key);
+        handlers.remove(registrationInfo);
         host.unregisterHandler(registrationInfo);
     }
 
@@ -400,4 +403,8 @@ public class UndertowComponent extends DefaultComponent implements RestConsumerF
     protected String getComponentName() {
         return "undertow";
     }
+
+    public Set<HttpHandlerRegistrationInfo> getHandlers() {
+        return handlers;
+    }
 }
diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowConsumer.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowConsumer.java
index 8abc793..4922d24 100644
--- a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowConsumer.java
+++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowConsumer.java
@@ -17,7 +17,9 @@
 package org.apache.camel.component.undertow;
 
 import java.io.IOException;
+import java.net.URI;
 import java.nio.ByteBuffer;
+import java.util.Collection;
 
 import io.undertow.Handlers;
 import io.undertow.server.HttpHandler;
@@ -31,6 +33,7 @@ import io.undertow.util.StatusCodes;
 import io.undertow.websockets.core.WebSocketChannel;
 
 import org.apache.camel.AsyncCallback;
+import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
 import org.apache.camel.Processor;
@@ -38,6 +41,9 @@ import org.apache.camel.TypeConverter;
 import org.apache.camel.component.undertow.UndertowConstants.EventType;
 import org.apache.camel.component.undertow.handlers.CamelWebSocketHandler;
 import org.apache.camel.impl.DefaultConsumer;
+import org.apache.camel.util.CollectionStringBuffer;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -92,15 +98,30 @@ public class UndertowConsumer extends DefaultConsumer implements HttpHandler {
         HttpString requestMethod = httpExchange.getRequestMethod();
 
         if (Methods.OPTIONS.equals(requestMethod) && !getEndpoint().isOptionsEnabled()) {
-            String allowedMethods;
-            if (getEndpoint().getHttpMethodRestrict() != null) {
-                allowedMethods = getEndpoint().getHttpMethodRestrict();
-                if (!allowedMethods.contains("OPTIONS")) {
-                    allowedMethods = "OPTIONS," + allowedMethods;
+            CollectionStringBuffer csb = new CollectionStringBuffer(",");
+
+            Collection<HttpHandlerRegistrationInfo> handlers = getEndpoint().getComponent().getHandlers();
+            for (HttpHandlerRegistrationInfo reg : handlers) {
+                URI uri = reg.getUri();
+                // what other HTTP methods may exists for the same path
+                if (reg.getMethodRestrict() != null && getEndpoint().getHttpURI().equals(uri)) {
+                    String restrict = reg.getMethodRestrict();
+                    if (restrict.endsWith(",OPTIONS")) {
+                        restrict = restrict.substring(0, restrict.length() - 8);
+                    }
+                    csb.append(restrict);
                 }
-            } else {
+            }
+            String allowedMethods = csb.toString();
+            if (ObjectHelper.isEmpty(allowedMethods)) {
+                allowedMethods = getEndpoint().getHttpMethodRestrict();
+            }
+            if (ObjectHelper.isEmpty(allowedMethods)) {
                 allowedMethods = "GET,HEAD,POST,PUT,DELETE,TRACE,OPTIONS,CONNECT,PATCH";
             }
+            if (!allowedMethods.contains("OPTIONS")) {
+                allowedMethods = allowedMethods + ",OPTIONS";
+            }
             //return list of allowed methods in response headers
             httpExchange.setStatusCode(StatusCodes.OK);
             httpExchange.getResponseHeaders().put(ExchangeHeaders.CONTENT_LENGTH, 0);
diff --git a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestUndertowHttpOptionsTest.java b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestUndertowHttpOptionsTest.java
index ebd7ce8..afbb6b2 100644
--- a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestUndertowHttpOptionsTest.java
+++ b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestUndertowHttpOptionsTest.java
@@ -43,6 +43,19 @@ public class RestUndertowHttpOptionsTest extends BaseUndertowTest {
         assertEquals("", exchange.getIn().getBody(String.class));
     }
 
+    @Test
+    public void testMultipleHttpOptions() {
+        Exchange exchange = template.request("undertow:http://localhost:" + getPort() + "/users/v1/options", new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(Exchange.HTTP_METHOD, "OPTIONS");
+            }
+        });
+        assertEquals(200, exchange.getOut().getHeader(Exchange.HTTP_RESPONSE_CODE));
+        assertEquals("GET,POST,OPTIONS", exchange.getOut().getHeader("ALLOW"));
+        assertEquals("", exchange.getOut().getBody(String.class));
+    }
+
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
@@ -56,7 +69,11 @@ public class RestUndertowHttpOptionsTest extends BaseUndertowTest {
                     .get("v1/customers")
                         .to("mock:customers")
                     .put("v1/{id}")
-                        .to("mock:id");
+                        .to("mock:id")
+                    .get("v1/options")
+                        .to("mock:options")
+                    .post("v1/options")
+                        .to("mock:options");
             }
         };
     }