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

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-spring-boot.git


The following commit(s) were added to refs/heads/main by this push:
     new 85209822dc1 CAMEL-21461: platform-http - add CORS support (#1299)
85209822dc1 is described below

commit 85209822dc1e34f024486de12a7c37efe4e82479
Author: Rinaldo Pitzer JĂșnior <[email protected]>
AuthorDate: Fri Dec 6 05:27:17 2024 -0300

    CAMEL-21461: platform-http - add CORS support (#1299)
---
 .../springboot/CamelRequestHandlerMapping.java     |  80 +++++++-
 .../SpringBootPlatformHttpCorsCredentialsTest.java | 201 +++++++++++++++++++++
 .../springboot/SpringBootPlatformHttpCorsTest.java | 137 +++++++++-----
 ...java => SpringBootPlatformHttpOptionsTest.java} | 112 ++++++------
 .../src/test/resources/application.properties      |   5 +-
 5 files changed, 417 insertions(+), 118 deletions(-)

diff --git 
a/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/CamelRequestHandlerMapping.java
 
b/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/CamelRequestHandlerMapping.java
index 33f43b30e8f..9eb332f45c4 100644
--- 
a/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/CamelRequestHandlerMapping.java
+++ 
b/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/CamelRequestHandlerMapping.java
@@ -23,8 +23,10 @@ import 
org.apache.camel.component.platform.http.PlatformHttpComponent;
 import org.apache.camel.component.platform.http.PlatformHttpEndpoint;
 import org.apache.camel.component.platform.http.PlatformHttpListener;
 import org.apache.camel.component.platform.http.spi.PlatformHttpEngine;
+import org.apache.camel.spi.RestConfiguration;
 import org.apache.camel.util.ReflectionHelper;
 import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.cors.CorsConfiguration;
 import org.springframework.web.method.HandlerMethod;
 import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
 import 
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
@@ -32,13 +34,20 @@ import org.springframework.web.util.ServletRequestPathUtils;
 
 import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 public class CamelRequestHandlerMapping extends RequestMappingHandlerMapping 
implements PlatformHttpListener {
 
     private final PlatformHttpComponent component;
     private final PlatformHttpEngine engine;
 
+    private CorsConfiguration corsConfiguration;
+
     public CamelRequestHandlerMapping(PlatformHttpComponent component, 
PlatformHttpEngine engine) {
         this.component = component;
         this.engine = engine;
@@ -67,6 +76,55 @@ public class CamelRequestHandlerMapping extends 
RequestMappingHandlerMapping imp
         return null;
     }
 
+    @Override
+    protected CorsConfiguration initCorsConfiguration(Object handler, Method 
method, RequestMappingInfo mappingInfo) {
+        RestConfiguration restConfiguration = 
component.getCamelContext().getRestConfiguration();
+
+        if (!restConfiguration.isEnableCORS()) {
+            // CORS disabled for camel
+            return null;
+        }
+
+        if (corsConfiguration == null) {
+            Map<String, String> corsHeaders = 
restConfiguration.getCorsHeaders();
+            corsConfiguration = createCorsConfiguration(corsHeaders != null ? 
corsHeaders : Collections.emptyMap());
+        }
+        return corsConfiguration;
+    }
+
+    @Override
+    protected CorsConfiguration getCorsConfiguration(Object handler, 
HttpServletRequest request) {
+        return super.getCorsConfiguration(handler, request);
+    }
+
+    private CorsConfiguration createCorsConfiguration(Map<String, String> 
corsHeaders) {
+        CorsConfiguration config = new CorsConfiguration();
+
+        String allowedOrigin = corsHeaders.get("Access-Control-Allow-Origin");
+        config.addAllowedOrigin(allowedOrigin != null ? allowedOrigin : 
RestConfiguration.CORS_ACCESS_CONTROL_ALLOW_ORIGIN);
+
+        String allowMethodsStr = 
corsHeaders.get("Access-Control-Allow-Methods");
+        allowMethodsStr = allowMethodsStr != null ? allowMethodsStr : 
RestConfiguration.CORS_ACCESS_CONTROL_ALLOW_METHODS;
+        for (String allowMethod : allowMethodsStr.split(",")) {
+            config.addAllowedMethod(allowMethod.trim());
+        }
+
+        String allowHeadersStr = 
corsHeaders.get("Access-Control-Allow-Headers");
+        allowHeadersStr = allowHeadersStr != null ? allowHeadersStr : 
RestConfiguration.CORS_ACCESS_CONTROL_ALLOW_HEADERS;
+        for (String allowHeader : allowHeadersStr.split(",")) {
+            config.addAllowedHeader(allowHeader.trim());
+        }
+
+        String maxAgeStr = corsHeaders.get("Access-Control-Max-Age");
+        Long maxAge = maxAgeStr != null ? Long.parseLong(maxAgeStr) : 
Long.parseLong(RestConfiguration.CORS_ACCESS_CONTROL_MAX_AGE);
+        config.setMaxAge(maxAge);
+
+        String allowCredentials = 
corsHeaders.get("Access-Control-Allow-Credentials");
+        config.setAllowCredentials(Boolean.parseBoolean(allowCredentials));
+
+        return config;
+    }
+
     @Override
     protected HandlerMethod getHandlerInternal(HttpServletRequest request) 
throws Exception {
         ServletRequestPathUtils.parseAndCache(request);
@@ -81,7 +139,6 @@ public class CamelRequestHandlerMapping extends 
RequestMappingHandlerMapping imp
         for (RequestMappingInfo info : requestMappingInfos) {
             // Needed in case of context reload
             unregisterMapping(info);
-
             registerMapping(info, model.getConsumer(), m);
         }
     }
@@ -100,20 +157,31 @@ public class CamelRequestHandlerMapping extends 
RequestMappingHandlerMapping imp
         if (verbs == null && model.getConsumer() != null) {
             PlatformHttpEndpoint endpoint = (PlatformHttpEndpoint) 
model.getConsumer().getEndpoint();
             verbs = endpoint.getHttpMethodRestrict();
-
-            for (RequestMethod rm : RequestMethod.values()) {
-                createRequestMappingInfo(model, rm, result);
+            if (verbs == null) {
+                Collections.addAll(methods, RequestMethod.values());
             }
         }
         if (verbs != null) {
             for (String v : model.getVerbs().split(",")) {
                 RequestMethod rm = RequestMethod.resolve(v);
                 methods.add(rm);
-
-                createRequestMappingInfo(model, rm, result);
             }
         }
 
+        if (component.getCamelContext().getRestConfiguration().isEnableCORS()) 
{
+            // when CORS is enabled Camel adds OPTIONS by default in 
httpMethodsRestrict
+            // which causes multiple registration of OPTIONS endpoints in 
spring.
+            // this causes issues when unregistering endpoints because others 
share
+            // the same handler (the consumer) so they get unregistered as 
well.
+            // removing the OPTIONS mappings maintains the intended behavior
+            // of this verb while avoiding this issue.
+            methods.remove(RequestMethod.OPTIONS);
+        }
+
+        for (RequestMethod rm : methods) {
+            createRequestMappingInfo(model, rm, result);
+        }
+
         return result;
     }
 
diff --git 
a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCorsCredentialsTest.java
 
b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCorsCredentialsTest.java
new file mode 100644
index 00000000000..b7a60072a3e
--- /dev/null
+++ 
b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCorsCredentialsTest.java
@@ -0,0 +1,201 @@
+/*
+ * 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.platform.http.springboot;
+
+import io.restassured.RestAssured;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spi.RestConfiguration;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import 
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration;
+import 
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.server.LocalServerPort;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.annotation.DirtiesContext;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.Matchers.*;
+
+@EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, 
SecurityAutoConfiguration.class})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
+@CamelSpringBootTest
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, 
classes = { CamelAutoConfiguration.class,
+        SpringBootPlatformHttpCorsCredentialsTest.class, 
SpringBootPlatformHttpCorsCredentialsTest.TestConfiguration.class,
+        PlatformHttpComponentAutoConfiguration.class, 
SpringBootPlatformHttpAutoConfiguration.class, })
+public class SpringBootPlatformHttpCorsCredentialsTest {
+
+    @LocalServerPort
+    private Integer port;
+
+    @BeforeEach
+    void setUp() {
+        RestAssured.port = port;
+        RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
+    }
+
+    @Configuration
+    public static class TestConfiguration {
+        @Bean
+        public RouteBuilder springBootPlatformHttpRestDSLRouteBuilder() {
+            return new RouteBuilder() {
+                @Override
+                public void configure() {
+                    restConfiguration().component("platform-http")
+                        .enableCORS(true)
+                        .corsAllowCredentials(true)
+                        .corsHeaderProperty("Access-Control-Allow-Origin", 
"http://custom.origin.springboot";);
+
+                    rest("/rest")
+                        .get().to("direct:restGet")
+                        
.post().consumes("application/json").to("direct:restPost");
+
+                    from("direct:restPost")
+                        .transform().constant("corsPost");
+
+                    from("direct:restGet")
+                        .transform().constant("corsGet");
+                }
+            };
+        }
+    }
+
+    @Test
+    public void get() {
+        given()
+            .when()
+            .get("/rest")
+            .then()
+            .statusCode(200)
+            .body(equalTo("corsGet"));
+    }
+
+    @Test
+    public void post() {
+        given()
+            .header("Content-type","application/json")
+            .when()
+            .post("/rest")
+            .then()
+            .statusCode(200)
+            .body(equalTo("corsPost"));
+    }
+
+    @Test
+    public void options() {
+        final String origin = "http://custom.origin.springboot";;
+        final String method = "POST";
+        final String headers = "X-Requested-With";
+
+        given()
+            .header("Origin", origin)
+            .header("Access-Control-Request-Method", method)
+            .header("Access-Control-Request-Headers", headers)
+            .when()
+            .options("/rest")
+            .then()
+            .statusCode(200)
+            .header("Access-Control-Allow-Origin", origin)
+            .header("Access-Control-Allow-Methods", containsString(method))
+            .header("Access-Control-Allow-Headers", containsString(headers))
+            .header("Access-Control-Allow-Credentials", "true")
+            .header("Access-Control-Max-Age", 
RestConfiguration.CORS_ACCESS_CONTROL_MAX_AGE)
+            .body(emptyString());
+    }
+
+    @Test
+    public void getForbiddenOrigin() {
+        final String origin = "http://custom2.origin.springboot";;
+
+        given()
+            .header("Origin", origin)
+            .when()
+            .get("/rest")
+            .then()
+            .statusCode(403);
+    }
+
+    @Test
+    public void postForbiddenOrigin() {
+        final String origin = "http://custom2.origin.springboot";;
+
+        given()
+            .header("Origin", origin)
+            .header("Content-type","application/json")
+            .when()
+            .post("/rest")
+            .then()
+            .statusCode(403);
+    }
+
+    @Test
+    public void optionsForbiddenOrigin() {
+        final String origin = "http://custom2.origin.springboot";;
+
+        given()
+            .header("Origin", origin)
+            .when()
+            .options("/rest")
+            .then()
+            .header("Access-Control-Allow-Origin", 
not(containsString(origin)));
+    }
+
+    @Test
+    public void optionsForbiddenMethod() {
+        String method = "DELETE";
+
+        given()
+            .header("Access-Control-Request-Method", method)
+            .when()
+            .options("/rest")
+            .then()
+            .header("Access-Control-Allow-Methods", 
not(containsString(method)));
+    }
+
+    @Test
+    public void optionsForbiddenHeader() {
+        String header = "X-Custom-Header";
+
+        given()
+            .header("Access-Control-Request-Headers", header)
+            .when()
+            .options("/rest")
+            .then()
+            .header("Access-Control-Allow-Headers", 
not(containsString(header)));
+    }
+
+    @Test
+    public void optionNonCors() {
+        given()
+            .when()
+            .options("/rest")
+            .then()
+            .statusCode(200)
+            .header("Allow", containsString("OPTIONS"))
+            .header("Allow", containsString("GET"))
+            .header("Allow", containsString("POST"))
+            .header("Allow", containsString("HEAD"))
+            .header("Allow", not(containsString("PATCH")))
+            .header("Allow", not(containsString("PUT")))
+            .header("Allow", not(containsString("DELETE")));
+    }
+    
+}
diff --git 
a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCorsTest.java
 
b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCorsTest.java
index 61ad34fecfb..fd7e3cd7f35 100644
--- 
a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCorsTest.java
+++ 
b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCorsTest.java
@@ -17,7 +17,6 @@
 package org.apache.camel.component.platform.http.springboot;
 
 import io.restassured.RestAssured;
-import org.apache.camel.CamelContext;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.spi.RestConfiguration;
 import org.apache.camel.spring.boot.CamelAutoConfiguration;
@@ -25,18 +24,19 @@ import 
org.apache.camel.test.spring.junit5.CamelSpringBootTest;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import 
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration;
 import 
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
 import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.web.client.TestRestTemplate;
 import org.springframework.boot.test.web.server.LocalServerPort;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.test.annotation.DirtiesContext;
 
 import static io.restassured.RestAssured.given;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.emptyString;
+import static org.hamcrest.Matchers.not;
 
 @EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, 
SecurityAutoConfiguration.class})
 @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@@ -46,33 +46,17 @@ import static io.restassured.RestAssured.given;
         PlatformHttpComponentAutoConfiguration.class, 
SpringBootPlatformHttpAutoConfiguration.class, })
 public class SpringBootPlatformHttpCorsTest {
 
-    @Autowired
-    TestRestTemplate restTemplate;
-
-    @Autowired
-    CamelContext camelContext;
-
     @LocalServerPort
     private Integer port;
 
     @BeforeEach
     void setUp() {
         RestAssured.port = port;
+        RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
     }
 
     @Configuration
     public static class TestConfiguration {
-
-//        @Bean
-//        public WebMvcConfigurer corsConfigurer() {
-//            return new WebMvcConfigurer() {
-//                @Override
-//                public void addCorsMappings(CorsRegistry registry) {
-//                    registry.addMapping("/**");
-//                }
-//            };
-//        }
-
         @Bean
         public RouteBuilder springBootPlatformHttpRestDSLRouteBuilder() {
             return new RouteBuilder() {
@@ -81,14 +65,12 @@ public class SpringBootPlatformHttpCorsTest {
                     
restConfiguration().component("platform-http").enableCORS(true);
 
                     rest("/rest")
-                            .post()
-                            .consumes("application/json")
-                            .to("direct:rest");
+                            
.post().consumes("application/json").to("direct:rest");
 
                     from("direct:rest")
                             .setBody(simple("Hello ${body}"));
 
-                    from("platform-http:/cors")
+                    from("platform-http:/cors?httpMethodRestrict=GET,POST")
                             .transform().constant("cors");
                 }
             };
@@ -96,39 +78,96 @@ public class SpringBootPlatformHttpCorsTest {
     }
 
     @Test
-    @Disabled("Test is failing, work in progress")
-    public void cors() {
+    public void get() {
+        given()
+            .when()
+            .get("/cors")
+            .then()
+            .statusCode(200);
+    }
+
+    @Test
+    public void post() {
+        given()
+            .header("Content-type","application/json")
+            .when()
+            .post("/rest")
+            .then()
+            .statusCode(200);
+    }
+
+    @Test
+    public void options() {
         final String origin = "http://custom.origin.springboot";;
-        final String methods = "GET,POST";
-        final String headers = "X-Custom";
+        final String method = "POST";
+        final String headers = "X-Requested-With";
 
         given()
-                .header("Origin", origin)
-                .header("Access-Control-Request-Method", methods)
-                .header("Access-Control-Request-Headers", headers)
-                .when()
-                .get("/cors")
-                .then()
-                .statusCode(200)
-                .header("Access-Control-Allow-Origin", origin)
-                .header("Access-Control-Allow-Methods", methods)
-                .header("Access-Control-Allow-Headers", headers);
+            .header("Origin", origin)
+            .header("Access-Control-Request-Method", method)
+            .header("Access-Control-Request-Headers", headers)
+            .when()
+            .options("/rest")
+            .then()
+            .statusCode(200)
+            .header("Access-Control-Allow-Origin", "*")
+            .header("Access-Control-Allow-Methods", containsString(method))
+            .header("Access-Control-Allow-Headers", containsString(headers))
+            .header("Access-Control-Max-Age", 
RestConfiguration.CORS_ACCESS_CONTROL_MAX_AGE)
+            .body(emptyString());
     }
 
     @Test
-    @Disabled("Test is failing, work in progress")
-    public void corsWithConsumes() {
+    public void optionsSecondEndPoint() {
         final String origin = "http://custom.origin.springboot";;
+        final String method = "POST";
+        final String headers = "X-Requested-With";
+
+        given()
+            .header("Origin", origin)
+            .header("Access-Control-Request-Method", method)
+            .header("Access-Control-Request-Headers", headers)
+            .when()
+            .options("/cors")
+            .then()
+            .statusCode(200)
+            .header("Access-Control-Allow-Origin", "*")
+            .header("Access-Control-Allow-Methods", containsString(method))
+            .header("Access-Control-Allow-Headers", containsString(headers))
+            .header("Access-Control-Max-Age", 
RestConfiguration.CORS_ACCESS_CONTROL_MAX_AGE)
+            .body(emptyString());
+    }
+
+    @Test
+    public void optionNonCORS() {
+        given()
+            .when()
+            .options("/rest")
+            .then()
+            .statusCode(200)
+            .header("Allow", containsString("OPTIONS"))
+            .header("Allow", not(containsString("GET")))
+            .header("Allow", containsString("POST"))
+            .header("Allow", not(containsString("HEAD")))
+            .header("Allow", not(containsString("PATCH")))
+            .header("Allow", not(containsString("PUT")))
+            .header("Allow", not(containsString("DELETE")));
+    }
 
+    @Test
+    public void optionNonCorsSecondEndpoint() {
         given()
-                .header("Origin", origin)
-                .when()
-                .options("/rest")
-                .then()
-                .statusCode(204)
-                .header("Access-Control-Allow-Origin", 
RestConfiguration.CORS_ACCESS_CONTROL_ALLOW_ORIGIN)
-                .header("Access-Control-Allow-Methods", 
RestConfiguration.CORS_ACCESS_CONTROL_ALLOW_METHODS)
-                .header("Access-Control-Allow-Headers", 
RestConfiguration.CORS_ACCESS_CONTROL_ALLOW_HEADERS)
-                .header("Access-Control-Max-Age", 
RestConfiguration.CORS_ACCESS_CONTROL_MAX_AGE);
+            .when()
+            .options("/cors")
+            .then()
+            .statusCode(200)
+            .header("Allow", containsString("OPTIONS"))
+            .header("Allow", containsString("GET"))
+            .header("Allow", containsString("POST"))
+            .header("Allow", containsString("HEAD"))
+            .header("Allow", not(containsString("PATCH")))
+            .header("Allow", not(containsString("PUT")))
+            .header("Allow", not(containsString("DELETE")));
     }
+
 }
diff --git 
a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCorsTest.java
 
b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpOptionsTest.java
similarity index 51%
copy from 
components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCorsTest.java
copy to 
components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpOptionsTest.java
index 61ad34fecfb..036dd359cf1 100644
--- 
a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCorsTest.java
+++ 
b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpOptionsTest.java
@@ -17,40 +17,30 @@
 package org.apache.camel.component.platform.http.springboot;
 
 import io.restassured.RestAssured;
-import org.apache.camel.CamelContext;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.spi.RestConfiguration;
 import org.apache.camel.spring.boot.CamelAutoConfiguration;
 import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
 import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import 
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration;
 import 
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
 import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.web.client.TestRestTemplate;
 import org.springframework.boot.test.web.server.LocalServerPort;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.test.annotation.DirtiesContext;
 
 import static io.restassured.RestAssured.given;
+import static org.hamcrest.Matchers.*;
 
 @EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, 
SecurityAutoConfiguration.class})
 @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
 @CamelSpringBootTest
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, 
classes = { CamelAutoConfiguration.class,
-        SpringBootPlatformHttpCorsTest.class, 
SpringBootPlatformHttpCorsTest.TestConfiguration.class,
+        SpringBootPlatformHttpOptionsTest.class, 
SpringBootPlatformHttpOptionsTest.TestConfiguration.class,
         PlatformHttpComponentAutoConfiguration.class, 
SpringBootPlatformHttpAutoConfiguration.class, })
-public class SpringBootPlatformHttpCorsTest {
-
-    @Autowired
-    TestRestTemplate restTemplate;
-
-    @Autowired
-    CamelContext camelContext;
+public class SpringBootPlatformHttpOptionsTest {
 
     @LocalServerPort
     private Integer port;
@@ -58,77 +48,77 @@ public class SpringBootPlatformHttpCorsTest {
     @BeforeEach
     void setUp() {
         RestAssured.port = port;
+        RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
     }
 
     @Configuration
     public static class TestConfiguration {
-
-//        @Bean
-//        public WebMvcConfigurer corsConfigurer() {
-//            return new WebMvcConfigurer() {
-//                @Override
-//                public void addCorsMappings(CorsRegistry registry) {
-//                    registry.addMapping("/**");
-//                }
-//            };
-//        }
-
         @Bean
         public RouteBuilder springBootPlatformHttpRestDSLRouteBuilder() {
             return new RouteBuilder() {
                 @Override
                 public void configure() {
-                    
restConfiguration().component("platform-http").enableCORS(true);
+                    
restConfiguration().component("platform-http").enableCORS(false);
 
                     rest("/rest")
-                            .post()
-                            .consumes("application/json")
-                            .to("direct:rest");
-
-                    from("direct:rest")
-                            .setBody(simple("Hello ${body}"));
+                        .get().to("direct:get")
+                        .post().to("direct:post");
+                    from("direct:get").transform().constant("get");
+                    from("direct:post").transform().constant("post");
 
-                    from("platform-http:/cors")
-                            .transform().constant("cors");
+                    
from("platform-http:/restRestricted?httpMethodRestrict=GET,PUT").transform().constant("restricted");
+                    
from("platform-http:/restDefault").transform().constant("default");
                 }
             };
         }
     }
 
     @Test
-    @Disabled("Test is failing, work in progress")
-    public void cors() {
-        final String origin = "http://custom.origin.springboot";;
-        final String methods = "GET,POST";
-        final String headers = "X-Custom";
-
+    public void optionsRest() {
         given()
-                .header("Origin", origin)
-                .header("Access-Control-Request-Method", methods)
-                .header("Access-Control-Request-Headers", headers)
-                .when()
-                .get("/cors")
-                .then()
-                .statusCode(200)
-                .header("Access-Control-Allow-Origin", origin)
-                .header("Access-Control-Allow-Methods", methods)
-                .header("Access-Control-Allow-Headers", headers);
+            .when()
+            .options("/rest")
+            .then()
+            .statusCode(200)
+            .header("Allow", containsString("OPTIONS"))
+            .header("Allow", containsString("GET"))
+            .header("Allow", containsString("POST"))
+            .header("Allow", containsString("HEAD"))
+            .header("Allow", not(containsString("PATCH")))
+            .header("Allow", not(containsString("PUT")))
+            .header("Allow", not(containsString("DELETE")));
     }
 
     @Test
-    @Disabled("Test is failing, work in progress")
-    public void corsWithConsumes() {
-        final String origin = "http://custom.origin.springboot";;
+    public void optionsRestRestricted() {
+        given()
+            .when()
+            .options("/restRestricted")
+            .then()
+            .statusCode(200)
+            .header("Allow", containsString("OPTIONS"))
+            .header("Allow", containsString("GET"))
+            .header("Allow", not(containsString("POST")))
+            .header("Allow", containsString("HEAD"))
+            .header("Allow", not(containsString("PATCH")))
+            .header("Allow", containsString("PUT"))
+            .header("Allow", not(containsString("DELETE")));
+    }
 
+    @Test
+    public void optionsRestDefault() {
         given()
-                .header("Origin", origin)
-                .when()
-                .options("/rest")
-                .then()
-                .statusCode(204)
-                .header("Access-Control-Allow-Origin", 
RestConfiguration.CORS_ACCESS_CONTROL_ALLOW_ORIGIN)
-                .header("Access-Control-Allow-Methods", 
RestConfiguration.CORS_ACCESS_CONTROL_ALLOW_METHODS)
-                .header("Access-Control-Allow-Headers", 
RestConfiguration.CORS_ACCESS_CONTROL_ALLOW_HEADERS)
-                .header("Access-Control-Max-Age", 
RestConfiguration.CORS_ACCESS_CONTROL_MAX_AGE);
+            .when()
+            .options("/restDefault")
+            .then()
+            .statusCode(200)
+            .header("Allow", containsString("OPTIONS"))
+            .header("Allow", containsString("GET"))
+            .header("Allow", containsString("POST"))
+            .header("Allow", containsString("HEAD"))
+            .header("Allow", containsString("PATCH"))
+            .header("Allow", containsString("PUT"))
+            .header("Allow", containsString("DELETE"));
     }
+
 }
diff --git 
a/components-starter/camel-platform-http-starter/src/test/resources/application.properties
 
b/components-starter/camel-platform-http-starter/src/test/resources/application.properties
index 21f8569b457..f3183eb5542 100644
--- 
a/components-starter/camel-platform-http-starter/src/test/resources/application.properties
+++ 
b/components-starter/camel-platform-http-starter/src/test/resources/application.properties
@@ -15,5 +15,6 @@
 ## limitations under the License.
 ## ---------------------------------------------------------------------------
 
-#logging.level.org.springframework.web: DEBUG
-#logging.level.org.springframework.boot.web: DEBUG
\ No newline at end of file
+#logging.level.org.springframework.web=TRACE
+#logging.level.org.springframework.boot.web=TRACE
+#spring.mvc.log-request-details=true

Reply via email to