You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by fm...@apache.org on 2025/01/08 08:25:17 UTC
(camel-spring-boot) 03/03: CAMEL-21461: Add features to Platform Http SB Starter
This is an automated email from the ASF dual-hosted git repository.
fmariani pushed a commit to branch camel-spring-boot-4.8.x
in repository https://gitbox.apache.org/repos/asf/camel-spring-boot.git
commit 527646878f836c4807c534ad3bc23e86306101e9
Author: Croway <fe...@gmail.com>
AuthorDate: Thu Oct 17 18:40:13 2024 +0200
CAMEL-21461: Add features to Platform Http SB Starter
Certification Tests + Minor Fixes
Add failing tests
Add ReaderCache Converter test
fix streaming large file test
header mapping is already done in DefaultHttpBinding
fix streaming
CSB-5889: Let's cache the body so that is can be read multiple times
CSB-5889: regen
Disable not implemented feature tests
Co-Authored-By: johnpoth <po...@gmail.com>
Handle Consumes only for methods with body
---
.../camel-platform-http-starter/pom.xml | 39 ++
.../springboot/CamelRequestHandlerMapping.java | 6 +-
.../http/springboot/PlatformHttpMessage.java | 8 +-
.../springboot/SpringBootPlatformHttpBinding.java | 10 +-
.../PlatformHttpAsyncRequestHandlingTest.java | 11 +-
.../platform/http/springboot/PlatformHttpBase.java | 3 +-
.../http/springboot/PlatformHttpStreamingTest.java | 6 +-
...pringBootPlatformHttpCamelIntegrationsTest.java | 105 ++++++
.../SpringBootPlatformHttpCertificationTest.java | 391 +++++++++++++++++++++
.../SpringBootPlatformHttpCookiesTest.java | 160 +++++++++
.../SpringBootPlatformHttpEngineTest.java | 253 +++++++++++++
...SpringBootPlatformHttpHandleWriteErrorTest.java | 4 +-
...pringBootPlatformHttpJacksonConverterTest.java} | 66 ++--
...pringBootPlatformHttpMultipleExecutorsTest.java | 4 +-
.../SpringBootPlatformHttpProxyTest.java | 109 ++++++
.../SpringBootPlatformHttpRestDSLTest.java | 4 +-
.../SpringBootPlatformHttpSessionTest.java | 174 +++++++++
.../SpringBootPlatformHttpSpringSessionTest.java | 67 ++++
.../springboot/SpringBootPlatformHttpTest.java | 4 +-
.../SpringBootPlatformHttpTypeConverterTest.java | 135 +++++++
.../SpringBootPlatformHttpValidationTest.java | 191 ++++++++++
pom.xml | 2 +
22 files changed, 1711 insertions(+), 41 deletions(-)
diff --git a/components-starter/camel-platform-http-starter/pom.xml b/components-starter/camel-platform-http-starter/pom.xml
index f3b66c9e3ca..ba8f36e6043 100644
--- a/components-starter/camel-platform-http-starter/pom.xml
+++ b/components-starter/camel-platform-http-starter/pom.xml
@@ -55,6 +55,24 @@
<version>${rest-assured-version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-security</artifactId>
+ <version>${spring-boot-version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.session</groupId>
+ <artifactId>spring-session-hazelcast</artifactId>
+ <version>${spring-session-hazelcast-version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.hazelcast</groupId>
+ <artifactId>hazelcast</artifactId>
+ <version>${hazelcast-version}</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
@@ -65,6 +83,27 @@
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.springboot</groupId>
+ <artifactId>camel-jackson-starter</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.springboot</groupId>
+ <artifactId>camel-http-starter</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.wiremock.integrations</groupId>
+ <artifactId>wiremock-spring-boot</artifactId>
+ <version>${wiremock-spring-boot-version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.springboot</groupId>
+ <artifactId>camel-jsonpath-starter</artifactId>
+ <scope>test</scope>
+ </dependency>
<!--START OF GENERATED CODE-->
<dependency>
<groupId>org.apache.camel.springboot</groupId>
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 380d69ce232..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
@@ -133,7 +133,7 @@ public class CamelRequestHandlerMapping extends RequestMappingHandlerMapping imp
@Override
public void registerHttpEndpoint(HttpEndpointModel model) {
- RequestMappingInfo info = asRequestMappingInfo(model);
+ List<RequestMappingInfo> requestMappingInfos = asRequestMappingInfo(model);
Method m = ReflectionHelper.findMethod(SpringBootPlatformHttpConsumer.class, "service",
HttpServletRequest.class, HttpServletResponse.class);
for (RequestMappingInfo info : requestMappingInfos) {
@@ -148,7 +148,9 @@ public class CamelRequestHandlerMapping extends RequestMappingHandlerMapping imp
// noop
}
- private RequestMappingInfo asRequestMappingInfo(HttpEndpointModel model) {
+ private List<RequestMappingInfo> asRequestMappingInfo(HttpEndpointModel model) {
+ List<RequestMappingInfo> result = new ArrayList<>();
+
// allowed methods from model or endpoint
List<RequestMethod> methods = new ArrayList<>();
String verbs = model.getVerbs();
diff --git a/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/PlatformHttpMessage.java b/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/PlatformHttpMessage.java
index 4e8abf92fe3..9d8e151ea38 100644
--- a/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/PlatformHttpMessage.java
+++ b/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/PlatformHttpMessage.java
@@ -20,6 +20,7 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.camel.Exchange;
import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.StreamCache;
import org.apache.camel.http.common.HttpBinding;
import org.apache.camel.support.DefaultMessage;
import org.apache.camel.util.ObjectHelper;
@@ -60,7 +61,12 @@ public class PlatformHttpMessage extends DefaultMessage {
if (flag != null && flag) {
this.setHeader("CamelSkipWwwFormUrlEncoding", Boolean.TRUE);
}
-
+ // we need to favor using stream cache so the body can be re-read later when routing the message
+ StreamCache newBody = camelContext.getTypeConverter().tryConvertTo(StreamCache.class,
+ exchange, getBody());
+ if (newBody != null) {
+ setBody(newBody);
+ }
binding.readRequest(request, this);
}
diff --git a/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpBinding.java b/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpBinding.java
index eea1e9a1904..d5e493a28b4 100644
--- a/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpBinding.java
+++ b/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpBinding.java
@@ -16,9 +16,16 @@
*/
package org.apache.camel.component.platform.http.springboot;
+import jakarta.activation.DataHandler;
+import jakarta.servlet.ServletContext;
+import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
-import org.apache.camel.Message;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.camel.*;
+import org.apache.camel.attachment.AttachmentMessage;
+import org.apache.camel.attachment.CamelFileDataSource;
import org.apache.camel.component.platform.http.PlatformHttpEndpoint;
+import org.apache.camel.converter.stream.CachedOutputStream;
import org.apache.camel.http.base.HttpHelper;
import org.apache.camel.http.common.DefaultHttpBinding;
import org.apache.camel.support.ExchangeHelper;
@@ -38,6 +45,7 @@ import java.util.Locale;
import java.util.UUID;
public class SpringBootPlatformHttpBinding extends DefaultHttpBinding {
+ private static final Logger LOG = LoggerFactory.getLogger(SpringBootPlatformHttpBinding.class);
protected void populateRequestParameters(HttpServletRequest request, Message message) {
super.populateRequestParameters(request, message);
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/PlatformHttpAsyncRequestHandlingTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/PlatformHttpAsyncRequestHandlingTest.java
index 302149febbf..1dcc7e50dd1 100644
--- a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/PlatformHttpAsyncRequestHandlingTest.java
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/PlatformHttpAsyncRequestHandlingTest.java
@@ -23,6 +23,8 @@ import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
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.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
@@ -32,14 +34,11 @@ import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
-@EnableAutoConfiguration
+@EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, SecurityAutoConfiguration.class})
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
@CamelSpringBootTest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { CamelAutoConfiguration.class,
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/PlatformHttpBase.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/PlatformHttpBase.java
index 79d5cb321d2..1e4fa6e7373 100644
--- a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/PlatformHttpBase.java
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/PlatformHttpBase.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.component.platform.http.springboot;
-import java.util.concurrent.TimeUnit;
import org.apache.camel.CamelContext;
import org.apache.camel.ServiceStatus;
import org.assertj.core.api.Assertions;
@@ -25,6 +24,8 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.web.client.TestRestTemplate;
+import java.util.concurrent.TimeUnit;
+
import static org.junit.jupiter.api.Assertions.assertEquals;
abstract class PlatformHttpBase {
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/PlatformHttpStreamingTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/PlatformHttpStreamingTest.java
index 05962f12349..86f3c056a90 100644
--- a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/PlatformHttpStreamingTest.java
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/PlatformHttpStreamingTest.java
@@ -24,7 +24,9 @@ import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
import org.apache.camel.util.IOHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
+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;
@@ -42,7 +44,7 @@ import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
-@SpringBootApplication
+@EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, SecurityAutoConfiguration.class})
@DirtiesContext
@CamelSpringBootTest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { CamelAutoConfiguration.class,
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCamelIntegrationsTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCamelIntegrationsTest.java
new file mode 100644
index 00000000000..29e5520165d
--- /dev/null
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCamelIntegrationsTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.BeforeEach;
+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;
+
+@EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, SecurityAutoConfiguration.class})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
+@CamelSpringBootTest
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { CamelAutoConfiguration.class,
+ SpringBootPlatformHttpCamelIntegrationsTest.class, SpringBootPlatformHttpCamelIntegrationsTest.TestConfiguration.class,
+ PlatformHttpComponentAutoConfiguration.class, SpringBootPlatformHttpAutoConfiguration.class, })
+public class SpringBootPlatformHttpCamelIntegrationsTest {
+
+ @Autowired
+ TestRestTemplate restTemplate;
+
+ @Autowired
+ CamelContext camelContext;
+
+ @LocalServerPort
+ private Integer port;
+
+ @BeforeEach
+ void setUp() {
+ RestAssured.port = port;
+ }
+
+ @Configuration
+ public static class TestConfiguration {
+
+ @Bean
+ public RouteBuilder springBootPlatformHttpRestDSLRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ rest().post("message").to("direct:route");
+ from("direct:route")
+ .choice()
+ .when().jsonpath("$[?(@.counter>0)]")
+ .setBody(constant("positive"))
+ .otherwise()
+ .setBody(constant("negative"))
+ .end();
+ }
+ };
+ }
+ }
+
+ @Test
+ public void test() {
+ String data = "{\"counter\":1}";
+ given()
+ .body(data)
+ .header("Content-Type", "application/json")
+ .when()
+ .post("/message")
+ .then()
+ .statusCode(200)
+ .body(Matchers.is("positive"));
+
+ data = "{\"counter\":0}";
+ given()
+ .body(data)
+ .header("Content-Type", "application/json")
+ .when()
+ .post("/message")
+ .then()
+ .statusCode(200)
+ .body(Matchers.is("negative"));
+ }
+}
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCertificationTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCertificationTest.java
new file mode 100644
index 00000000000..39c9305bc6b
--- /dev/null
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCertificationTest.java
@@ -0,0 +1,391 @@
+/*
+ * 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 io.restassured.http.ContentType;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.platform.http.cookie.CookieConfiguration;
+import org.apache.camel.component.platform.http.cookie.CookieHandler;
+import org.apache.camel.model.rest.RestBindingMode;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+import org.apache.camel.util.IOHelper;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
+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.server.LocalServerPort;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.annotation.DirtiesContext;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Map;
+import java.util.Random;
+
+import static io.restassured.RestAssured.given;
+import static io.restassured.matcher.RestAssuredMatchers.detailedCookie;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, SecurityAutoConfiguration.class})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
+@CamelSpringBootTest
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { CamelAutoConfiguration.class,
+ SpringBootPlatformHttpCertificationTest.class, SpringBootPlatformHttpCertificationTest.TestConfiguration.class,
+ PlatformHttpComponentAutoConfiguration.class, SpringBootPlatformHttpAutoConfiguration.class, })
+public class SpringBootPlatformHttpCertificationTest extends PlatformHttpBase {
+
+ private static final String postRouteId = "SpringBootPlatformHttpRestDSLTest_mypost";
+ private static final String getRouteId = "SpringBootPlatformHttpRestDSLTest_myget";
+
+ @LocalServerPort
+ private Integer port;
+
+ @BeforeEach
+ void setUp() {
+ RestAssured.port = port;
+ }
+
+ @Configuration
+ public static class TestConfiguration {
+
+ @Bean
+ public RouteBuilder springBootPlatformHttpRestDSLRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ getCamelContext().getStreamCachingStrategy().setSpoolEnabled(true);
+ rest()
+ .get("myget").id(getRouteId).to("direct:get")
+ .post("mypost").id(postRouteId).to("direct:post");
+
+ from("direct:post").transform().body(String.class, b -> b.toUpperCase());
+ from("direct:get").setBody().constant("get")
+ .log("hello");
+
+ rest("rest").get("/test")
+ .consumes("application/json,application/xml")
+ .produces("application/json,application/xml")
+ .bindingMode(RestBindingMode.auto)
+ .to("direct:rest");
+
+ rest("rest").post("/test")
+ .consumes("application/json,application/xml")
+ .produces("application/json,application/xml")
+ .bindingMode(RestBindingMode.auto)
+ .to("direct:rest");
+
+ from("direct:rest")
+ .setBody(simple("Hello"));
+
+ from("platform-http:/streaming?useStreaming=true")
+ .log("Done echoing back request body as response body");
+
+ from("platform-http:/helloStreaming?useStreaming=true")
+ .transform().simple("Hello ${body}");
+
+ from("platform-http:/streamingFileRequestResponseBody?useStreaming=true")
+ .log("Done processing request");
+
+ from("platform-http:/streamingWithFormUrlEncodedBody?useStreaming=true")
+ .setBody().simple("foo = ${header.foo}");
+
+ from("platform-http:/streamingWithSpecificEncoding?useStreaming=true")
+ .log("Done echoing back request body as response body");
+
+ from("platform-http:/streamingWithClosedInputStreamResponse?useStreaming=true")
+ .process(new Processor() {
+ @Override
+ public void process(Exchange exchange) throws Exception {
+ // Simulate an error processing an input stream by closing it ahead of the response being written
+ // Verifies the response promise.fail is called correctly
+ InputStream stream = getClass().getResourceAsStream("/application.properties");
+ if (stream != null) {
+ stream.close();
+ }
+ exchange.getMessage().setBody(stream);
+ }
+ });
+
+ from("platform-http:/streamingWithUnconvertableResponseType?useStreaming=true")
+ .process(new Processor() {
+ @Override
+ public void process(Exchange exchange) {
+ // Force a type conversion exception and verify the response promise.fail is called correctly
+ exchange.getMessage().setBody(new TestBean());
+ }
+ })
+ .log("Conversion done");
+
+ from("platform-http:/session")
+ .setBody().constant("session");
+
+ from("platform-http:/streamingWithLargeRequestAndResponseBody?useStreaming=true")
+ .log("Done echoing back request body as response body");
+
+ from("platform-http:/addCookie?useCookieHandler=true")
+ .process(exchange -> {
+ exchange.getProperty(Exchange.COOKIE_HANDLER, CookieHandler.class).addCookie("foo", "bar");
+ })
+ .setBody().constant("add");
+ }
+ };
+ }
+ }
+
+ @Override
+ protected String getPostRouteId() {
+ return postRouteId;
+ }
+
+ @Override
+ protected String getGetRouteId() {
+ return getRouteId;
+ }
+
+ @Test
+ public void testLoad() throws Exception {
+ waitUntilRouteIsStarted(1, getGetRouteId());
+
+ for (int i = 0; i < 1_000; i++) {
+ Assertions.assertThat(restTemplate.getForEntity("/myget", String.class).getStatusCode().value()).isEqualTo(200);
+ }
+ }
+
+ @Test
+ public void nonSupportedContentType() {
+ RestAssured.given()
+ .header("Content-Type", "notSupported")
+ .post("rest/test")
+ .then()
+ .statusCode(415);
+ }
+
+ @Test
+ public void oneContentType() {
+ RestAssured.given()
+ .header("Content-type", ContentType.XML)
+ .header("Accept", ContentType.XML)
+ .get("rest/test")
+ .then()
+ .statusCode(200)
+ .body(is("Hello"));
+ }
+
+ @Test
+ public void noContentTypeOkForGet() {
+ RestAssured.given()
+ .get("rest/test")
+ .then()
+ .statusCode(200)
+ .body(is("\"Hello\""));
+ }
+
+ @Test
+ public void nonSupportedAccept() {
+ RestAssured.given()
+ .header("Content-type", ContentType.XML)
+ .header("Accept", ContentType.BINARY)
+ .get("rest/test")
+ .then()
+ .statusCode(406);
+ }
+
+ @Test
+ public void streaming() {
+ String requestBody = "Vert.x Platform HTTP";
+ given()
+ .body(requestBody)
+ .post("/helloStreaming")
+ .then()
+ .statusCode(200)
+ .body(is("Hello " + requestBody));
+ }
+
+ @Test
+ void streamingFileRequestResponseBody() throws Exception {
+ String content = "Hello World";
+ Path testFile = Files.createTempFile("platform-http-testing", "txt");
+ Files.writeString(testFile, content);
+
+ given()
+ .body(testFile.toFile())
+ .post("/streamingFileRequestResponseBody")
+ .then()
+ .statusCode(200)
+ .body(is(content));
+ }
+
+ @Test
+ void streamingWithFormUrlEncodedBody() throws Exception {
+ given()
+ .contentType(ContentType.URLENC)
+ .formParam("foo", "bar")
+ .post("/streamingWithFormUrlEncodedBody")
+ .then()
+ .statusCode(200)
+ .body(is("foo = bar"));
+ }
+
+ @Test
+ void streamingWithSpecificEncoding() throws Exception {
+ Path input = Files.createTempFile("platform-http-input", "dat");
+ Path output = Files.createTempFile("platform-http-output", "dat");
+
+ String fileContent = "Content with special character ð";
+ Files.writeString(input, fileContent, StandardCharsets.ISO_8859_1);
+
+ InputStream response = given()
+ .body(new FileInputStream(input.toFile()))
+ .post("/streamingWithSpecificEncoding")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body()
+ .asInputStream();
+
+ try (FileOutputStream fos = new FileOutputStream(output.toFile())) {
+ IOHelper.copy(response, fos);
+ }
+
+ assertEquals(fileContent, Files.readString(output, StandardCharsets.ISO_8859_1));
+ }
+
+ @Test
+ @Disabled("Test is failing, work in progress")
+ void streamingWithClosedInputStreamResponse() throws Exception {
+
+ given()
+ .get("/streamingWithClosedInputStreamResponse")
+ .then()
+ .statusCode(500);
+ }
+
+ @Test
+ void streamingWithUnconvertableResponseType() throws Exception {
+ given()
+ .get("/streamingWithUnconvertableResponseType")
+ .then()
+ .statusCode(500);
+ }
+
+ static final class TestBean {
+ }
+
+ @Test
+ public void session() {
+ Map<String, String> cookies = given()
+ .when()
+ .get("/session")
+ .then()
+ .statusCode(200)
+// .cookie("vertx-web.session",
+// detailedCookie()
+// .path("/").value(notNullValue())
+// .httpOnly(false)
+// .secured(false)
+// .sameSite("Strict"))
+// .header("cookie", nullValue())
+ .body(equalTo("session"))
+ .extract().cookies();
+
+ System.out.println(cookies);
+ }
+
+ @Autowired
+ CamelContext camelContext;
+
+ @Test
+ @DisabledIfSystemProperty(named = "ci.env.name", matches = "apache.org",
+ disabledReason = "File too large for Apache CI")
+ void streamingWithLargeRequestAndResponseBody() throws Exception {
+ camelContext.getStreamCachingStrategy().setSpoolEnabled(true);
+
+ Path input = createLargeFile();
+ Path output = Files.createTempFile("platform-http-output", "dat");
+
+ InputStream response = given()
+ .body(new FileInputStream(input.toFile()))
+ .post("/streaming")
+ .then()
+ .extract()
+ .asInputStream();
+
+ try (FileOutputStream fos = new FileOutputStream(output.toFile())) {
+ IOHelper.copy(response, fos);
+ }
+
+ assertEquals(input.toFile().length(), output.toFile().length());
+ }
+
+ private Path createLargeFile() throws IOException {
+ // Create a 4GB file containing random data
+ Path path = Files.createTempFile("platform-http-input", "dat");
+ try (FileOutputStream fos = new FileOutputStream(path.toFile())) {
+ Random random = new Random();
+ long targetFileSize = (long) (4 * Math.pow(1024, 3));
+ long bytesWritten = 0L;
+
+ byte[] data = new byte[1024];
+ while (bytesWritten < targetFileSize) {
+ random.nextBytes(data);
+ fos.write(data);
+ bytesWritten += data.length;
+ }
+ }
+ return path;
+ }
+
+ private static CookieHandler getCookieHandler(Exchange exchange) {
+ return exchange.getProperty(Exchange.COOKIE_HANDLER, CookieHandler.class);
+ }
+
+ @Test
+ @Disabled("Test is failing, work in progress")
+ public void testAddCookie() throws Exception {
+ given()
+ .when()
+ .get("/addCookie")
+ .then()
+ .statusCode(200)
+ .cookie("foo",
+ detailedCookie()
+ .value("bar")
+ .path(CookieConfiguration.DEFAULT_PATH)
+ .domain((String) null)
+ .sameSite(CookieConfiguration.DEFAULT_SAME_SITE.getValue()))
+ .body(equalTo("add"));
+ }
+}
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCookiesTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCookiesTest.java
new file mode 100644
index 00000000000..830e22381c1
--- /dev/null
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCookiesTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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 jakarta.servlet.http.Cookie;
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+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.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 java.util.Arrays;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.startsWith;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, SecurityAutoConfiguration.class})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
+@CamelSpringBootTest
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { CamelAutoConfiguration.class,
+ SpringBootPlatformHttpCookiesTest.class, SpringBootPlatformHttpCookiesTest.TestConfiguration.class,
+ PlatformHttpComponentAutoConfiguration.class, SpringBootPlatformHttpAutoConfiguration.class, })
+public class SpringBootPlatformHttpCookiesTest {
+
+ @Autowired
+ TestRestTemplate restTemplate;
+
+ @Autowired
+ CamelContext camelContext;
+
+ @LocalServerPort
+ private Integer port;
+
+ @BeforeEach
+ void setUp() {
+ RestAssured.port = port;
+ }
+
+ @Configuration
+ public static class TestConfiguration {
+
+ @Bean
+ public RouteBuilder springBootPlatformHttpRestDSLRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("platform-http:/add")
+ .process(exchange -> {
+ PlatformHttpMessage message = (PlatformHttpMessage) exchange.getMessage();
+ message.getResponse().addCookie(new Cookie("foo", "bar"));
+ })
+ .setBody().constant("add");
+
+ from("platform-http:/remove")
+ .process(exchange -> {
+ PlatformHttpMessage message = (PlatformHttpMessage) exchange.getMessage();
+
+ Cookie cookie = Arrays.stream(message.getRequest().getCookies()).findFirst().get();
+ cookie.setMaxAge(0);
+ cookie.setValue(null);
+
+ message.getResponse().addCookie(cookie);
+ })
+ .setBody().constant("remove");
+
+ from("platform-http:/replace")
+ .process(exchange -> {
+ PlatformHttpMessage message = (PlatformHttpMessage) exchange.getMessage();
+ assertEquals(1, message.getRequest().getCookies().length);
+
+ Cookie cookie = new Cookie("XSRF-TOKEN", "88533580000c314");
+ cookie.setPath("/");
+ message.getResponse().addCookie(cookie);
+ })
+ .setBody().constant("replace");
+
+ from("platform-http:/echo")
+ .setBody().constant("echo");
+ }
+ };
+ }
+ }
+
+ @Test
+ public void addCookie() {
+ given()
+ .header("cookie", "foo=bar")
+ .when()
+ .get("/add")
+ .then()
+ .statusCode(200)
+ .header("set-cookie", "foo=bar")
+ .body(equalTo("add"));
+ }
+
+ @Test
+ public void removeCookie() {
+ given()
+ .header("cookie", "foo=bar")
+ .when()
+ .get("/remove")
+ .then()
+ .statusCode(200)
+ .header("set-cookie", startsWith("foo=; Max-Age=0; Expires="))
+ .body(equalTo("remove"));
+ }
+
+ @Test
+ public void replaceCookie() {
+ given()
+ .header("cookie", "XSRF-TOKEN=c359b44aef83415")
+ .when()
+ .get("/replace")
+ .then()
+ .statusCode(200)
+ .header("set-cookie", "XSRF-TOKEN=88533580000c314; Path=/")
+ .body(equalTo("replace"));
+ }
+
+ @Test
+ public void echoCookie() {
+ given()
+ .header("cookie", "echo=cookie")
+ .when()
+ .get("/echo")
+ .then()
+ .statusCode(200)
+ .header("cookie", startsWith("echo=cookie"))
+ .body(equalTo("echo"));
+ }
+
+}
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpEngineTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpEngineTest.java
new file mode 100644
index 00000000000..01d3885965e
--- /dev/null
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpEngineTest.java
@@ -0,0 +1,253 @@
+/*
+ * 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 io.restassured.http.ContentType;
+import jakarta.activation.DataHandler;
+import org.apache.camel.CamelContext;
+import org.apache.camel.attachment.AttachmentMessage;
+import org.apache.camel.builder.RouteBuilder;
+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 java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.Collections;
+
+import static io.restassured.RestAssured.get;
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+
+@EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, SecurityAutoConfiguration.class})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
+@CamelSpringBootTest
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { CamelAutoConfiguration.class,
+ SpringBootPlatformHttpEngineTest.class, SpringBootPlatformHttpEngineTest.TestConfiguration.class,
+ PlatformHttpComponentAutoConfiguration.class, SpringBootPlatformHttpAutoConfiguration.class, })
+public class SpringBootPlatformHttpEngineTest {
+ private final static String attachmentId = "myTestFile";
+
+ @Autowired
+ TestRestTemplate restTemplate;
+
+ @Autowired
+ CamelContext camelContext;
+
+ @LocalServerPort
+ private Integer port;
+
+ @BeforeEach
+ void setUp() {
+ RestAssured.port = port;
+ }
+
+ @Configuration
+ public static class TestConfiguration {
+
+ @Bean
+ public RouteBuilder springBootPlatformHttpRestDSLRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ rest()
+ .post("upload").to("direct:upload");
+
+ from("direct:upload")
+ .process(exchange -> {
+ AttachmentMessage message = exchange.getMessage(AttachmentMessage.class);
+ DataHandler attachment = message.getAttachment(attachmentId);
+ message.setBody(attachment.getContent());
+ });
+
+ from("platform-http:/form/post")
+ .convertBodyTo(String.class);
+
+ from("platform-http:/greeting/{name}?matchOnUriPrefix=true")
+ .transform().simple("Hello ${header.name}");
+
+ from("platform-http:/text/post")
+ .log("POST:/test/post has body ${body}");
+
+ from("platform-http:/responseHeaders")
+ .setHeader("nonEmptyFromRoute", constant("nonEmptyFromRouteValue"))
+ .setHeader("emptyFromRoute", constant(""))
+ .setBody().simple("Hello World");
+
+ from("platform-http:/multipleHeaders")
+ .setHeader("nonEmptyFromRoute", constant("nonEmptyFromRouteValue"))
+ .setBody().simple("Hello World");
+
+ from("platform-http:/consumerSuspended")
+ .routeId("consumerSuspended")
+ .setBody().constant("get");
+
+ from("platform-http:/error/response")
+ // Set the response to something that can't be type converted
+ .setBody().constant(Collections.EMPTY_SET);
+
+ from("platform-http:/error/query/param")
+ .setBody().constant("Error");
+ }
+ };
+ }
+ }
+
+ @Test
+ public void testAttachment() throws Exception {
+ final String attachmentId = "myTestFile";
+ final String fileContent = "Test multipart upload content";
+ final File tempFile = File.createTempFile("platform-http", ".txt");
+
+ Files.write(tempFile.toPath(), fileContent.getBytes(StandardCharsets.UTF_8));
+
+ given()
+ .multiPart(attachmentId, tempFile)
+ .when()
+ .post("/upload")
+ .then()
+ .statusCode(200)
+ .body(is(fileContent));
+ }
+
+ @Test
+ public void formPost() {
+ given()
+ .formParam("foo", "bar")
+ .formParam("cheese", "wine")
+ .when()
+ .post("/form/post")
+ .then()
+ .statusCode(200)
+ .body(is("foo=bar&cheese=wine"));
+ }
+
+ @Test
+ @Disabled("Test is failing, work in progress")
+ public void matchOnUriPrefix() {
+ final String greeting = "Hello Camel";
+ given()
+ .when()
+ .get("/greeting")
+ .then()
+ .statusCode(404);
+
+ given()
+ .when()
+ .get("/greeting/Camel")
+ .then()
+ .statusCode(200)
+ .body(equalTo(greeting));
+
+ given()
+ .when()
+ .get("/greeting/Camel/other/path/")
+ .then()
+ .statusCode(200)
+ .body(equalTo(greeting));
+ }
+
+ @Test
+ public void textContentPost() {
+ String payload = "Hello World";
+ given()
+ .contentType(ContentType.TEXT)
+ .body(payload)
+ .when()
+ .post("/text/post")
+ .then()
+ .statusCode(200)
+ .body(is(payload));
+ }
+
+ @Test
+ public void responseHeaders() {
+ RestAssured.given()
+ .header("nonEmpty", "nonEmptyValue")
+ .header("empty", "")
+ .get("/responseHeaders")
+ .then()
+ .statusCode(200)
+ .body(equalTo("Hello World"))
+ .header("nonEmpty", "nonEmptyValue")
+ .header("empty", "")
+ .header("nonEmptyFromRoute", "nonEmptyFromRouteValue")
+ .header("emptyFromRoute", "");
+ }
+
+ @Test
+ public void multipleHeaders() {
+ RestAssured.given()
+ .header("nonEmpty", "nonEmptyValue")
+ .header("empty", "")
+ .get("/multipleHeaders?duplicated=1&duplicated=2")
+ .then()
+ .statusCode(200)
+ .body(equalTo("Hello World"))
+ .header("nonEmpty", "nonEmptyValue")
+ .header("nonEmptyFromRoute", "nonEmptyFromRouteValue");
+ }
+
+ @Test
+ @Disabled("Test is failing, work in progress")
+ public void consumerSuspended() throws Exception {
+ given()
+ .when()
+ .get("/consumerSuspended")
+ .then()
+ .statusCode(200)
+ .body(equalTo("get"));
+
+ camelContext.getRouteController().suspendRoute("consumerSuspended");
+
+ given()
+ .when()
+ .get("/get")
+ .then()
+ .statusCode(503);
+ }
+
+ @Test
+ public void responseTypeConversionErrorHandled() {
+ get("/error/response")
+ .then()
+ .statusCode(500);
+ }
+
+ @Test
+ @Disabled("Test is failing, work in progress")
+ public void responseBadQueryParamErrorHandled() {
+ get("/error/query/param?::")
+ .then()
+ .statusCode(500);
+ }
+}
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpHandleWriteErrorTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpHandleWriteErrorTest.java
index 37a3cb384bb..4be423aab44 100644
--- a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpHandleWriteErrorTest.java
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpHandleWriteErrorTest.java
@@ -30,6 +30,8 @@ import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
import org.assertj.core.api.Assertions;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -39,7 +41,7 @@ import org.springframework.test.annotation.DirtiesContext.ClassMode;
import java.io.IOException;
-@EnableAutoConfiguration
+@EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, SecurityAutoConfiguration.class})
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
@CamelSpringBootTest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { CamelAutoConfiguration.class,
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpRestDSLTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpJacksonConverterTest.java
similarity index 51%
copy from components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpRestDSLTest.java
copy to components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpJacksonConverterTest.java
index b6761b9877d..afda83e5c9d 100644
--- a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpRestDSLTest.java
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpJacksonConverterTest.java
@@ -16,31 +16,50 @@
*/
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.component.jackson.JacksonConstants;
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.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 org.springframework.test.annotation.DirtiesContext.ClassMode;
-@EnableAutoConfiguration
-@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.Matchers.equalTo;
+
+@EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, SecurityAutoConfiguration.class})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@CamelSpringBootTest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { CamelAutoConfiguration.class,
- SpringBootPlatformHttpRestDSLTest.class, SpringBootPlatformHttpRestDSLTest.TestConfiguration.class,
+ SpringBootPlatformHttpJacksonConverterTest.class, SpringBootPlatformHttpJacksonConverterTest.TestConfiguration.class,
PlatformHttpComponentAutoConfiguration.class, SpringBootPlatformHttpAutoConfiguration.class, })
-public class SpringBootPlatformHttpRestDSLTest extends PlatformHttpBase {
+public class SpringBootPlatformHttpJacksonConverterTest {
+
+ @Autowired
+ TestRestTemplate restTemplate;
+
+ @Autowired
+ CamelContext camelContext;
- private static final String postRouteId = "SpringBootPlatformHttpRestDSLTest_mypost";
+ @LocalServerPort
+ private Integer port;
- private static final String getRouteId = "SpringBootPlatformHttpRestDSLTest_myget";
+ @BeforeEach
+ void setUp() {
+ RestAssured.port = port;
+ }
- // *************************************
- // Config
- // *************************************
@Configuration
public static class TestConfiguration {
@@ -49,24 +68,23 @@ public class SpringBootPlatformHttpRestDSLTest extends PlatformHttpBase {
return new RouteBuilder() {
@Override
public void configure() {
- rest()
- .get("myget").id(getRouteId).to("direct:get")
- .post("mypost").id(postRouteId).to("direct:post");
+ getContext().getGlobalOptions().put(JacksonConstants.ENABLE_TYPE_CONVERTER, "true");
- from("direct:post").transform().body(String.class, b -> b.toUpperCase());
- from("direct:get").setBody().constant("get");
+ from("platform-http:/hello")
+ .setBody().constant("{\"hello\": \"world\"}")
+ .unmarshal().json();
}
};
}
}
- @Override
- protected String getPostRouteId() {
- return postRouteId;
- }
-
- @Override
- protected String getGetRouteId() {
- return getRouteId;
+ @Test
+ public void jacksonTypeConverter() {
+ given()
+ .when()
+ .get("/hello")
+ .then()
+ .statusCode(200)
+ .body(equalTo("{\"hello\":\"world\"}"));
}
-}
+}
\ No newline at end of file
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpMultipleExecutorsTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpMultipleExecutorsTest.java
index 7e51f3644db..7d0816d7c52 100644
--- a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpMultipleExecutorsTest.java
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpMultipleExecutorsTest.java
@@ -23,6 +23,8 @@ import org.assertj.core.api.Assertions;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -33,7 +35,7 @@ import org.springframework.test.annotation.DirtiesContext;
import java.util.List;
import java.util.concurrent.Executor;
-@EnableAutoConfiguration
+@EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, SecurityAutoConfiguration.class})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@CamelSpringBootTest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { CamelAutoConfiguration.class,
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpProxyTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpProxyTest.java
new file mode 100644
index 00000000000..fe75c7ad177
--- /dev/null
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpProxyTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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 com.github.tomakehurst.wiremock.client.WireMock;
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+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.beans.factory.annotation.Value;
+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 org.wiremock.spring.ConfigureWireMock;
+import org.wiremock.spring.EnableWireMock;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.Matchers.containsString;
+
+@EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, SecurityAutoConfiguration.class})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
+@CamelSpringBootTest
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { CamelAutoConfiguration.class,
+ SpringBootPlatformHttpProxyTest.class, SpringBootPlatformHttpProxyTest.TestConfiguration.class,
+ PlatformHttpComponentAutoConfiguration.class, SpringBootPlatformHttpAutoConfiguration.class, })
+@EnableWireMock(@ConfigureWireMock(portProperties = "customPort"))
+public class SpringBootPlatformHttpProxyTest {
+
+ @Value("${wiremock.server.baseUrl}")
+ private String wiremockUrl;
+
+ @Autowired
+ TestRestTemplate restTemplate;
+
+ @Autowired
+ CamelContext camelContext;
+
+ @LocalServerPort
+ private Integer port;
+
+ @BeforeEach
+ void setUp() {
+ RestAssured.port = port;
+ WireMock.stubFor(get(urlPathEqualTo("/"))
+ .willReturn(aResponse()
+ .withBody(
+ "{\"message\": \"Hello World\"}")));
+ }
+
+ @Configuration
+ public static class TestConfiguration {
+
+ @Bean
+ public RouteBuilder springBootPlatformHttpRestDSLRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("platform-http:proxy?useStreaming=false")
+ .log("${headers}")
+ .toD("${headers." + Exchange.HTTP_URI + "}?bridgeEndpoint=true");
+ }
+ };
+ }
+ }
+
+ @Test
+ @Disabled("Test is failing, work in progress")
+ public void httpProxy() {
+ final var proxyURI = "http://localhost:" + RestAssured.port;
+
+ final var originURI = wiremockUrl;
+
+ given()
+ .proxy(proxyURI)
+ .contentType(ContentType.JSON)
+ .when().get(originURI)
+ .then()
+ .statusCode(200)
+ .body(containsString("{\"message\": \"Hello World\"}"));
+ }
+}
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpRestDSLTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpRestDSLTest.java
index b6761b9877d..c9e4b5b17f6 100644
--- a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpRestDSLTest.java
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpRestDSLTest.java
@@ -20,13 +20,15 @@ import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.spring.boot.CamelAutoConfiguration;
import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
-@EnableAutoConfiguration
+@EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, SecurityAutoConfiguration.class})
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
@CamelSpringBootTest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { CamelAutoConfiguration.class,
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpSessionTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpSessionTest.java
new file mode 100644
index 00000000000..5f09e6a7d01
--- /dev/null
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpSessionTest.java
@@ -0,0 +1,174 @@
+/*
+ * 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 io.restassured.http.Cookie;
+import io.restassured.internal.ValidatableResponseImpl;
+import io.restassured.response.Response;
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+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.security.config.Customizer;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.test.annotation.DirtiesContext;
+
+import static io.restassured.RestAssured.given;
+
+@EnableAutoConfiguration
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
+@CamelSpringBootTest
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { CamelAutoConfiguration.class,
+ SpringBootPlatformHttpSessionTest.class, SpringBootPlatformHttpSessionTest.TestConfiguration.class,
+ PlatformHttpComponentAutoConfiguration.class, SpringBootPlatformHttpAutoConfiguration.class, })
+public class SpringBootPlatformHttpSessionTest {
+
+ @Autowired
+ TestRestTemplate restTemplate;
+
+ @Autowired
+ CamelContext camelContext;
+
+ @LocalServerPort
+ private Integer port;
+
+ @BeforeEach
+ void setUp() {
+ RestAssured.port = port;
+ }
+
+ @Configuration
+ @EnableWebSecurity
+ public static class TestConfiguration {
+
+ @Bean
+ public UserDetailsService userDetailsService() {
+ UserDetails user = User.builder()
+ .username("user")
+ .password("{noop}password")
+ .authorities("USER")
+ .build();
+
+ UserDetails admin = User.builder()
+ .username("admin")
+ .password("{noop}password")
+ .authorities("ADMIN")
+ .build();
+
+ return new InMemoryUserDetailsManager(user, admin);
+ }
+
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+ return http
+ .csrf(httpSecurityCsrfConfigurer -> httpSecurityCsrfConfigurer.disable())
+ .authorizeHttpRequests(authorizeRequests ->
+ authorizeRequests.anyRequest().authenticated())
+ .httpBasic(Customizer.withDefaults())
+ .build();
+ }
+
+ @Bean
+ public RouteBuilder springBootPlatformHttpRestDSLRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ rest("/authenticated")
+ .post("/first")
+ .to("direct:first")
+ .get("/second")
+ .to("direct:second");
+
+ from("direct:first")
+ .process(exchange -> {
+ PlatformHttpMessage message = (PlatformHttpMessage) exchange.getMessage();
+ message.getRequest().getSession()
+ .setAttribute("json-attribute", exchange.getMessage().getBody(String.class));
+ });
+
+ from("direct:second")
+ .process(exchange -> {
+ PlatformHttpMessage message = (PlatformHttpMessage) exchange.getMessage();
+
+ exchange.getIn().setBody(
+ message.getRequest().getSession().getAttribute("json-attribute"));
+ });
+ }
+ };
+ }
+ }
+
+ protected String getSessionKey() {
+ return "JSESSIONID";
+ }
+
+ @Test
+ public void session() {
+ String jsonAttribute = """
+ {"test":"attribute"}
+ """;
+
+ var result = given()
+ .auth().basic("user", "password")
+ .body(jsonAttribute)
+ .when()
+ .post("/authenticated/first")
+ .then()
+ .statusCode(200)
+ .cookie(getSessionKey());
+
+ String session = ((ValidatableResponseImpl) result).originalResponse().cookies().get(getSessionKey());
+
+ result = given()
+ .auth().basic("user", "password")
+ .cookie(new Cookie.Builder(getSessionKey(), session).build())
+ .when()
+ .get("/authenticated/second")
+ .then()
+ .statusCode(200)
+ .body(Matchers.is(jsonAttribute));
+
+ Response response = ((ValidatableResponseImpl) result).originalResponse();
+
+ result = given()
+ .auth().basic("admin", "password")
+ .when()
+ .get("/authenticated/second")
+ .then()
+ .statusCode(204)
+ .body(Matchers.is(""));
+
+ response = ((ValidatableResponseImpl) result).originalResponse();
+ }
+}
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpSpringSessionTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpSpringSessionTest.java
new file mode 100644
index 00000000000..531bb8c8f8e
--- /dev/null
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpSpringSessionTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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 com.hazelcast.config.*;
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.core.HazelcastInstance;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.session.hazelcast.HazelcastIndexedSessionRepository;
+import org.springframework.session.hazelcast.PrincipalNameExtractor;
+import org.springframework.session.hazelcast.config.annotation.web.http.EnableHazelcastHttpSession;
+import org.springframework.test.annotation.DirtiesContext;
+
+@EnableAutoConfiguration
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
+@CamelSpringBootTest
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { CamelAutoConfiguration.class,
+ SpringBootPlatformHttpSpringSessionTest.class, SpringBootPlatformHttpSpringSessionTest.TestConfiguration.class,
+ SpringBootPlatformHttpSessionTest.TestConfiguration.class,
+ PlatformHttpComponentAutoConfiguration.class, SpringBootPlatformHttpAutoConfiguration.class, })
+public class SpringBootPlatformHttpSpringSessionTest extends SpringBootPlatformHttpSessionTest {
+
+ @Override
+ protected String getSessionKey() {
+ return "SESSION";
+ }
+
+ @Configuration
+ @EnableHazelcastHttpSession(maxInactiveIntervalInSeconds = 150)
+ public static class TestConfiguration {
+
+ @Bean(destroyMethod = "shutdown")
+ public HazelcastInstance hazelcastInstance() {
+ Config config = new Config();
+ NetworkConfig networkConfig = config.getNetworkConfig();
+ networkConfig.setPort(0);
+ networkConfig.getJoin().getAutoDetectionConfig().setEnabled(false);
+ AttributeConfig attributeConfig = new AttributeConfig()
+ .setName(HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE)
+ .setExtractorClassName(PrincipalNameExtractor.class.getName());
+ config.getMapConfig(HazelcastIndexedSessionRepository.DEFAULT_SESSION_MAP_NAME)
+ .addAttributeConfig(attributeConfig)
+ .addIndexConfig(
+ new IndexConfig(IndexType.HASH, HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE));
+ return Hazelcast.newHazelcastInstance(config);
+ }
+ }
+}
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpTest.java
index 77355b21277..a844a15f2a8 100644
--- a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpTest.java
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpTest.java
@@ -20,13 +20,15 @@ import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.spring.boot.CamelAutoConfiguration;
import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
-@EnableAutoConfiguration
+@EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, SecurityAutoConfiguration.class})
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
@CamelSpringBootTest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { CamelAutoConfiguration.class,
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpTypeConverterTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpTypeConverterTest.java
new file mode 100644
index 00000000000..2b567e130c9
--- /dev/null
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpTypeConverterTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.*;
+import org.apache.camel.builder.RouteBuilder;
+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.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 java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Map;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.Matchers.equalTo;
+
+@EnableAutoConfiguration(exclude = {OAuth2ClientAutoConfiguration.class, SecurityAutoConfiguration.class})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
+@CamelSpringBootTest
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { CamelAutoConfiguration.class,
+ SpringBootPlatformHttpTypeConverterTest.class, SpringBootPlatformHttpTypeConverterTest.TestConfiguration.class,
+ PlatformHttpComponentAutoConfiguration.class, SpringBootPlatformHttpAutoConfiguration.class, })
+public class SpringBootPlatformHttpTypeConverterTest {
+
+ @Autowired
+ TestRestTemplate restTemplate;
+
+ @Autowired
+ CamelContext camelContext;
+
+ @LocalServerPort
+ private Integer port;
+
+ @BeforeEach
+ void setUp() {
+ RestAssured.port = port;
+ }
+
+ @Configuration
+ public static class TestConfiguration {
+
+ @Bean
+ public RouteBuilder springBootPlatformHttpRestDSLRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ getContext().getTypeConverterRegistry().addTypeConverter(InputStream.class,
+ Map.class,
+ new InputStreamTypeConverter());
+
+ from("platform-http:/inputstream")
+ .routeId("inputstream")
+ .setBody().constant(Collections.singletonMap("is", "my-test"));
+ }
+ };
+ }
+ }
+
+ @Test
+ public void customTypeConverter() {
+ given()
+ .when()
+ .get("/inputstream")
+ .then()
+ .statusCode(200)
+ .body(equalTo("InputStream:my-test"));
+ }
+
+ static class InputStreamTypeConverter implements TypeConverter {
+ @Override
+ public boolean allowNull() {
+ return false;
+ }
+
+ @Override
+ public <T> T convertTo(Class<T> type, Object value) throws TypeConversionException {
+ return null;
+ }
+
+ @Override
+ public <T> T convertTo(Class<T> type, Exchange exchange, Object value) throws TypeConversionException {
+ byte[] out = ("InputStream:" + ((Map) value).get("is")).getBytes(StandardCharsets.UTF_8);
+ return type.cast(new ByteArrayInputStream(out));
+ }
+
+ @Override
+ public <T> T mandatoryConvertTo(Class<T> type, Object value) throws TypeConversionException, NoTypeConversionAvailableException {
+ return null;
+ }
+
+ @Override
+ public <T> T mandatoryConvertTo(Class<T> type, Exchange exchange, Object value) throws TypeConversionException, NoTypeConversionAvailableException {
+ return null;
+ }
+
+ @Override
+ public <T> T tryConvertTo(Class<T> type, Object value) {
+ return null;
+ }
+
+ @Override
+ public <T> T tryConvertTo(Class<T> type, Exchange exchange, Object value) {
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpValidationTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpValidationTest.java
new file mode 100644
index 00000000000..4e3d1ed7983
--- /dev/null
+++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpValidationTest.java
@@ -0,0 +1,191 @@
+/*
+ * 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 io.restassured.http.ContentType;
+import io.restassured.response.ValidatableResponse;
+import io.restassured.specification.RequestSpecification;
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.platform.http.spi.Method;
+import org.apache.camel.model.rest.RestBindingMode;
+import org.apache.camel.model.rest.RestParamType;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+import org.hamcrest.Matcher;
+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 java.util.List;
+
+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,
+ SpringBootPlatformHttpValidationTest.class, SpringBootPlatformHttpValidationTest.TestConfiguration.class,
+ PlatformHttpComponentAutoConfiguration.class, SpringBootPlatformHttpAutoConfiguration.class, })
+public class SpringBootPlatformHttpValidationTest {
+
+ @Autowired
+ TestRestTemplate restTemplate;
+
+ @Autowired
+ CamelContext camelContext;
+
+ @LocalServerPort
+ private Integer port;
+
+ @BeforeEach
+ void setUp() {
+ RestAssured.port = port;
+ }
+
+ @Configuration
+ public static class TestConfiguration {
+
+ @Bean
+ public RouteBuilder springBootPlatformHttpRestDSLRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ rest("/rest")
+ .post("/validate/body")
+ .clientRequestValidation(true)
+ .param().name("body").type(RestParamType.body).required(true).endParam()
+ .to("direct:rest");
+ from("direct:rest")
+ .setBody(simple("Hello ${body}"));
+
+ from("platform-http:/echo")
+ .setBody().simple("${body}");
+
+ from("platform-http:/test")
+ .setBody().simple("Hello ${body[method]}");
+
+ rest("/invalidContentTypeClientRequestValidation")
+ .clientRequestValidation(true)
+ .bindingMode(RestBindingMode.json)
+ .post("/validate/body")
+ .consumes("text/plain")
+ .produces("application/json")
+ .to("direct:invalidContentTypeClientRequestValidation");
+ from("direct:invalidContentTypeClientRequestValidation")
+ .setBody(simple("Hello ${body}"));
+ }
+ };
+ }
+ }
+
+ @Test
+ public void requestValidation() throws Exception {
+ given()
+ .when()
+ .post("/rest/validate/body")
+ .then()
+ .statusCode(400)
+ .body(is("The request body is missing."));
+
+ given()
+ .body(" ")
+ .when()
+ .post("/rest/validate/body")
+ .then()
+ .statusCode(400)
+ .body(is("The request body is missing."));
+
+ given()
+ .body("Camel Platform HTTP Vert.x")
+ .when()
+ .post("/rest/validate/body")
+ .then()
+ .statusCode(200)
+ .body(is("Hello Camel Platform HTTP Vert.x"));
+ }
+
+ @Test
+ @Disabled("Test is failing, work in progress")
+ public void requestBodyAllowed() {
+ for (Method method : Method.values()) {
+ ValidatableResponse validatableResponse = given()
+ .contentType(ContentType.JSON)
+ .when()
+ .body("{\"method\": \"" + method + "\"}")
+ .request(method.name(), "/echo")
+ .then()
+ .statusCode(200);
+
+ Matcher<String> expectedBody;
+ if (method.equals(Method.HEAD)) {
+ // HEAD response body is ignored
+ validatableResponse.body(emptyString());
+ } else {
+ validatableResponse.body("method", equalTo(method.name()));
+ }
+ }
+ }
+
+ @Test
+ @Disabled("Test is failing, work in progress")
+ public void requestBodyAllowedFormUrlEncoded() {
+ final List<Method> methodsWithBodyAllowed = List.of(Method.POST, Method.PUT, Method.PATCH, Method.DELETE);
+
+ RequestSpecification request = given()
+ .when()
+ .contentType(ContentType.URLENC);
+
+ for (Method method : Method.values()) {
+ if (methodsWithBodyAllowed.contains(method)) {
+ request.body("method=" + method)
+ .request(method.name(), "/test")
+ .then()
+ .statusCode(200)
+ .body(equalTo("Hello " + method));
+ } else {
+ request.body(method)
+ .request(method.name(), "/test")
+ .then()
+ .statusCode(500);
+ }
+ }
+ }
+
+ @Test
+ public void invalidContentTypeClientRequestValidation() {
+ given()
+ .when()
+ .body("{\"name\": \"Donald\"}")
+ .contentType("application/json")
+ .post("/invalidContentTypeClientRequestValidation/validate/body")
+ .then()
+ .statusCode(415);
+ }
+}
diff --git a/pom.xml b/pom.xml
index c4e05800c76..48ee423ea2a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -131,6 +131,8 @@
<surefire.version>${maven-surefire-plugin-version}</surefire.version>
<swagger-parser-v3-version>2.1.10</swagger-parser-v3-version>
<cyclonedx-maven-plugin-version>2.8.1</cyclonedx-maven-plugin-version>
+ <wiremock-spring-boot-version>3.0.2</wiremock-spring-boot-version>
+ <spring-session-hazelcast-version>3.3.2</spring-session-hazelcast-version>
</properties>