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

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


The following commit(s) were added to refs/heads/main by this push:
     new 34bf4efd7d Complete vertx-http test coverage #4658 (#4708)
34bf4efd7d is described below

commit 34bf4efd7dbd3f2adb2265a20fb456849fc7ffef
Author: Alexandre Gallice <[email protected]>
AuthorDate: Wed Mar 29 14:01:48 2023 +0200

    Complete vertx-http test coverage #4658 (#4708)
    
    * vertx-http: complete test coverage #4658
    
    * vertx-http: add test coverage for multipart form data #4658
    
    * vertx-http: add test of custom vertxOptions
    
    * vertx-http: add session management test
    
    * vertx-http: add test coverage for buffer conversion with dynamic encoding
    
    * vertx-http: complete allowJavaSerializedObject doc
---
 .../pages/reference/extensions/vertx-http.adoc     |  15 +++
 .../runtime/src/main/doc/configuration.adoc        |   8 ++
 integration-tests/http/pom.xml                     |   4 +
 .../quarkus/component/http/it/HttpResource.java    | 107 +++++++++++++++++++++
 .../camel/quarkus/component/http/it/HttpRoute.java |   3 +
 .../quarkus/component/http/it/HttpService.java     |  59 ++++++++++++
 ...e.java => VertxClientRelatedBeansProducer.java} |  36 +++----
 .../http/src/main/resources/application.properties |   1 +
 .../camel/quarkus/component/http/it/HttpTest.java  |  67 +++++++++++++
 9 files changed, 282 insertions(+), 18 deletions(-)

diff --git a/docs/modules/ROOT/pages/reference/extensions/vertx-http.adoc 
b/docs/modules/ROOT/pages/reference/extensions/vertx-http.adoc
index 6ab4f34ed2..82dd75c911 100644
--- a/docs/modules/ROOT/pages/reference/extensions/vertx-http.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/vertx-http.adoc
@@ -55,3 +55,18 @@ You will also need to enable serialization for the exception 
classes that you in
 ----
 @RegisterForReflection(targets = { IllegalStateException.class, 
MyCustomException.class }, serialization = true)
 ----
+
+[id="extensions-vertx-http-additional-camel-quarkus-configuration"]
+== Additional Camel Quarkus configuration
+
+[id="extensions-vertx-http-configuration-allowjavaserializedobject-option-in-native-mode"]
+== allowJavaSerializedObject option in native mode
+
+When using the `allowJavaSerializedObject` option in native mode, the support 
of serialization might need to be enabled.
+Please, refer to the xref:user-guide/native-mode.adoc#serialization[native 
mode user guide] for more information.
+
+[id="extensions-vertx-http-configuration-character-encodings"]
+=== Character encodings
+
+Check the xref:user-guide/native-mode.adoc#charsets[Character encodings 
section] of the Native mode guide if the application is expected to send and 
receive requests using non-default encodings.
+
diff --git a/extensions/vertx-http/runtime/src/main/doc/configuration.adoc 
b/extensions/vertx-http/runtime/src/main/doc/configuration.adoc
new file mode 100644
index 0000000000..431ced5e7c
--- /dev/null
+++ b/extensions/vertx-http/runtime/src/main/doc/configuration.adoc
@@ -0,0 +1,8 @@
+== allowJavaSerializedObject option in native mode
+
+When using the `allowJavaSerializedObject` option in native mode, the support 
of serialization might need to be enabled.
+Please, refer to the xref:user-guide/native-mode.adoc#serialization[native 
mode user guide] for more information.
+
+=== Character encodings
+
+Check the xref:user-guide/native-mode.adoc#charsets[Character encodings 
section] of the Native mode guide if the application is expected to send and 
receive requests using non-default encodings.
diff --git a/integration-tests/http/pom.xml b/integration-tests/http/pom.xml
index ecf338fd83..ab2905b83b 100644
--- a/integration-tests/http/pom.xml
+++ b/integration-tests/http/pom.xml
@@ -99,6 +99,10 @@
             <artifactId>quarkus-junit4-mock</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-multipart-provider</artifactId>
+        </dependency>
 
         <!-- test dependencies - camel-quarkus -->
         <dependency>
diff --git 
a/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/HttpResource.java
 
b/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/HttpResource.java
index 92a8f5d35d..15acdc449c 100644
--- 
a/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/HttpResource.java
+++ 
b/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/HttpResource.java
@@ -22,6 +22,8 @@ import java.nio.charset.StandardCharsets;
 import java.util.Base64;
 import java.util.zip.GZIPInputStream;
 
+import io.vertx.core.buffer.Buffer;
+import io.vertx.ext.web.multipart.MultipartForm;
 import jakarta.annotation.security.RolesAllowed;
 import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.inject.Inject;
@@ -38,13 +40,19 @@ import jakarta.ws.rs.core.Response;
 import org.apache.camel.ConsumerTemplate;
 import org.apache.camel.Exchange;
 import org.apache.camel.FluentProducerTemplate;
+import org.apache.camel.Message;
+import org.apache.camel.PropertyBindingException;
+import org.apache.camel.ResolveEndpointFailedException;
 import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.EndpointConsumerBuilder;
 import org.apache.camel.builder.EndpointProducerBuilder;
 import org.apache.camel.builder.endpoint.EndpointRouteBuilder;
+import org.apache.camel.http.base.HttpOperationFailedException;
 import org.apache.camel.util.IOHelper;
 import org.eclipse.microprofile.config.ConfigProvider;
 
+import static 
org.apache.camel.component.vertx.http.VertxHttpConstants.CONTENT_TYPE_FORM_URLENCODED;
+
 @Path("/test/client")
 @ApplicationScoped
 public class HttpResource {
@@ -378,6 +386,105 @@ public class HttpResource {
         return exchange.getException().getClass().getName();
     }
 
+    @Path("/vertx-http/multipart-form-params")
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public String vertxHttpMultipartFormParams(@QueryParam("test-port") int 
port,
+            @QueryParam("organization") String organization,
+            @QueryParam("project") String project) {
+        return producerTemplate
+                
.toF("vertx-http:http://localhost:%d/service/multipart-form-params";, port)
+                .withBody("organization=" + organization + "&project=" + 
project)
+                .withHeader(Exchange.CONTENT_TYPE, 
CONTENT_TYPE_FORM_URLENCODED)
+                .request(String.class);
+    }
+
+    @Path("/vertx-http/multipart-form-data")
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public String vertxHttpMultipartFormData(@QueryParam("test-port") int 
port) {
+
+        MultipartForm form = MultipartForm.create();
+        form.binaryFileUpload("part-1", "test1.txt", 
Buffer.buffer("part1=content1".getBytes(StandardCharsets.UTF_8)),
+                "text/plain");
+        form.binaryFileUpload("part-2", "test2.xml",
+                Buffer.buffer("<part2 
value=\"content2\"/>".getBytes(StandardCharsets.UTF_8)), "text/xml");
+
+        return producerTemplate
+                
.toF("vertx-http:http://localhost:%d/service/multipart-form-data";, port)
+                .withBody(form)
+                .request(String.class);
+    }
+
+    @Path("/vertx-http/custom-vertx-options")
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public String vertxHttpCustomVertxOptions(@QueryParam("test-port") int 
port) {
+        try {
+            producerTemplate
+                    
.toF("vertx-http:http://localhost:%d/service/custom-vertx-options?vertxOptions=#myVertxOptions";,
 port)
+                    .request();
+            return "NOT_EXPECTED: the custom vertxOptions should have 
triggered a ResolveEndpointFailedException";
+        } catch (ResolveEndpointFailedException refex) {
+            Throwable firstLevelExceptionCause = refex.getCause();
+            if (firstLevelExceptionCause instanceof PropertyBindingException) {
+                if (firstLevelExceptionCause.getCause() instanceof 
IllegalArgumentException) {
+                    return "OK: the custom vertxOptions has triggered the 
expected exception";
+                }
+                return "NOT_EXPECTED: the 2nd level exception cause should be 
of type IllegalArgumentException";
+            } else {
+                return "NOT_EXPECTED: the 1st level exception cause should be 
of type PropertyBindingException";
+            }
+        }
+    }
+
+    @Path("/vertx-http/session-management")
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public String vertxHttpSessionManagement(@QueryParam("test-port") int 
port) {
+        String vertxHttpBaseUri = "vertx-http:http://localhost:"; + port + 
"/service/session-management";
+        Exchange result = producerTemplate
+                
.toF("%s/secure?sessionManagement=true&cookieStore=#myVertxCookieStore", 
vertxHttpBaseUri)
+                .request(Exchange.class);
+
+        HttpOperationFailedException exception = 
result.getException(HttpOperationFailedException.class);
+        if (exception.getStatusCode() != 403) {
+            return "NOT_EXPECTED: The first request in the session is expected 
to return HTTP 403";
+        }
+
+        result = producerTemplate
+                
.toF("%s/login?sessionManagement=true&cookieStore=#myVertxCookieStore", 
vertxHttpBaseUri)
+                .withHeader("username", "my-username")
+                .withHeader("password", "my-password")
+                .request(Exchange.class);
+
+        Message msg = result.getMessage();
+        if (msg == null) {
+            return "NOT_EXPECTED: The second request in the session should 
return a message";
+        } else {
+            String setCookieHeader = msg.getHeader("Set-Cookie", String.class);
+            if (setCookieHeader == null || 
!setCookieHeader.contains("sessionId=my-session-id-123")) {
+                return "NOT_EXPECTED: The message should have a Set-Cookie 
String header containing \"sessionId=my-session-id-123\"";
+            }
+        }
+
+        return producerTemplate
+                
.toF("%s/secure?sessionManagement=true&cookieStore=#myVertxCookieStore", 
vertxHttpBaseUri)
+                .request(String.class);
+    }
+
+    @Path("/vertx-http/buffer-conversion-with-charset")
+    @GET
+    public byte[] vertxBufferConversionWithCharset(@QueryParam("string") 
String string, @QueryParam("charset") String charset) {
+        Buffer buffer = producerTemplate
+                .to("direct:vertx-http-buffer-conversion-with-charset")
+                .withBody(string)
+                .withHeader(Exchange.CONTENT_TYPE, "text/plain;charset=" + 
charset)
+                .request(Buffer.class);
+
+        return buffer.getBytes();
+    }
+
     // *****************************
     //
     // Send dynamic tests
diff --git 
a/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/HttpRoute.java
 
b/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/HttpRoute.java
index 4f4311d761..393857a7f6 100644
--- 
a/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/HttpRoute.java
+++ 
b/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/HttpRoute.java
@@ -19,6 +19,7 @@ package org.apache.camel.quarkus.component.http.it;
 import java.io.InputStream;
 
 import io.quarkus.runtime.annotations.RegisterForReflection;
+import io.vertx.core.buffer.Buffer;
 import jakarta.inject.Named;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
@@ -76,6 +77,8 @@ public class HttpRoute extends RouteBuilder {
         
from("netty-http:http://0.0.0.0:{{camel.netty-http.test-port}}/test/server/myService";)
                 .transform().constant("Hello from myService");
 
+        from("direct:vertx-http-buffer-conversion-with-charset")
+                .convertBodyTo(Buffer.class);
     }
 
     @Named
diff --git 
a/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/HttpService.java
 
b/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/HttpService.java
index 54e1594690..ead9323b87 100644
--- 
a/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/HttpService.java
+++ 
b/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/HttpService.java
@@ -16,13 +16,21 @@
  */
 package org.apache.camel.quarkus.component.http.it;
 
+import java.util.Map;
+
 import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.CookieParam;
+import jakarta.ws.rs.ForbiddenException;
+import jakarta.ws.rs.FormParam;
 import jakarta.ws.rs.GET;
+import jakarta.ws.rs.HeaderParam;
 import jakarta.ws.rs.POST;
 import jakarta.ws.rs.Path;
 import jakarta.ws.rs.Produces;
 import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.NewCookie;
+import jakarta.ws.rs.core.Response;
 
 @Path("/service")
 @ApplicationScoped
@@ -41,4 +49,55 @@ public class HttpService {
     public String toUpper(String message) {
         return message.toUpperCase();
     }
+
+    @POST
+    @Path("/multipart-form-params")
+    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String multipartFormParams(@FormParam("organization") String 
organization, @FormParam("project") String project) {
+        return String.format("multipartFormParams(%s, %s)", organization, 
project);
+    }
+
+    @POST
+    @Path("/multipart-form-data")
+    @Consumes(MediaType.MULTIPART_FORM_DATA)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String multipartFormData(Map<String, String> parts) {
+        if (parts.size() != 2 || !parts.keySet().contains("part-1") || 
!parts.keySet().contains("part-2")) {
+            throw new IllegalArgumentException(
+                    "There should be exactly 2 parts named \"part-1\" and 
\"parts-2\" in the multipart upload");
+        }
+        return String.format("multipartFormData(%s, %s)", parts.get("part-1"), 
parts.get("part-2"));
+    }
+
+    @GET
+    @Path("/custom-vertx-options")
+    public void customVertxOptions() {
+        // We are not expected to pass here as the Vert.x HTTP client should 
throw IllegalArgumentException 
+    }
+
+    @GET
+    @Path("/session-management/secure")
+    @Produces(MediaType.TEXT_PLAIN)
+    public String getSecuredContent(@CookieParam("sessionId") String cookie) {
+        if ("my-session-id-123".equals(cookie)) {
+            return "Some secret content";
+        } else {
+            throw new ForbiddenException("A cookie with session id is needed 
to access the secured content");
+        }
+    }
+
+    @GET
+    @Path("/session-management/login")
+    @Produces(MediaType.TEXT_PLAIN)
+    public Response login(@HeaderParam("username") String username, 
@HeaderParam("password") String password) {
+        if ("my-username".equals(username) && "my-password".equals(password)) {
+            NewCookie cookie = new NewCookie.Builder("sessionId")
+                    .value("my-session-id-123")
+                    .build();
+            return Response.ok().cookie(cookie).build();
+        }
+        throw new ForbiddenException("Wrong username/password, no cookie will 
be created");
+    }
+
 }
diff --git 
a/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/HttpService.java
 
b/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/VertxClientRelatedBeansProducer.java
similarity index 61%
copy from 
integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/HttpService.java
copy to 
integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/VertxClientRelatedBeansProducer.java
index 54e1594690..3f6949d0c2 100644
--- 
a/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/HttpService.java
+++ 
b/integration-tests/http/src/main/java/org/apache/camel/quarkus/component/http/it/VertxClientRelatedBeansProducer.java
@@ -16,29 +16,29 @@
  */
 package org.apache.camel.quarkus.component.http.it;
 
+import io.vertx.core.VertxOptions;
+import io.vertx.ext.web.client.spi.CookieStore;
 import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.Path;
+import jakarta.inject.Named;
+import jakarta.inject.Singleton;
 import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
 
-@Path("/service")
 @ApplicationScoped
-public class HttpService {
-    @Path("/get")
-    @GET
-    @Produces(MediaType.TEXT_PLAIN)
-    public String get() {
-        return "get";
+public class VertxClientRelatedBeansProducer {
+
+    @Singleton
+    @Produces
+    @Named("myVertxOptions")
+    VertxOptions createOptions() {
+        // Setting an inconsistent value to generate an 
IllegalArgumentException on first Vertx.x HTTP client request
+        return new VertxOptions().setMaxEventLoopExecuteTime(0);
     }
 
-    @Path("/toUpper")
-    @POST
-    @Consumes(MediaType.TEXT_PLAIN)
-    @Produces(MediaType.TEXT_PLAIN)
-    public String toUpper(String message) {
-        return message.toUpperCase();
+    @ApplicationScoped
+    @Produces
+    @Named("myVertxCookieStore")
+    CookieStore createCookieStore() {
+        return CookieStore.build();
     }
+
 }
diff --git a/integration-tests/http/src/main/resources/application.properties 
b/integration-tests/http/src/main/resources/application.properties
index ba7b64fb33..ed8496c3a9 100644
--- a/integration-tests/http/src/main/resources/application.properties
+++ b/integration-tests/http/src/main/resources/application.properties
@@ -19,6 +19,7 @@
 # Quarkus
 #
 quarkus.native.resources.includes = jsse/*,restcountries/*
+quarkus.native.add-all-charsets = true
 quarkus.camel.native.reflection.serialization-enabled = true
 
 # Basic authentication configuration
diff --git 
a/integration-tests/http/src/test/java/org/apache/camel/quarkus/component/http/it/HttpTest.java
 
b/integration-tests/http/src/test/java/org/apache/camel/quarkus/component/http/it/HttpTest.java
index e9d330bc5f..f8280a3383 100644
--- 
a/integration-tests/http/src/test/java/org/apache/camel/quarkus/component/http/it/HttpTest.java
+++ 
b/integration-tests/http/src/test/java/org/apache/camel/quarkus/component/http/it/HttpTest.java
@@ -34,6 +34,7 @@ import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.empty;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.not;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
 
 @QuarkusTest
 @QuarkusTestResource(HttpTestResource.class)
@@ -220,6 +221,72 @@ class HttpTest {
                 .body(is("Handled HttpOperationFailedException"));
     }
 
+    @Test
+    public void vertxHttpMultipartFormParamsShouldSucceed() {
+        RestAssured
+                .given()
+                .queryParam("test-port", RestAssured.port)
+                .queryParam("organization", "Apache")
+                .queryParam("project", "Camel")
+                .when()
+                .get("/test/client/vertx-http/multipart-form-params")
+                .then()
+                .statusCode(200)
+                .body(is("multipartFormParams(Apache, Camel)"));
+    }
+
+    @Test
+    public void vertxHttpMultipartFormDataShouldSucceed() {
+        RestAssured
+                .given()
+                .queryParam("test-port", RestAssured.port)
+                .when()
+                .get("/test/client/vertx-http/multipart-form-data")
+                .then()
+                .statusCode(200)
+                .body(is("multipartFormData(part1=content1, <part2 
value=\"content2\"/>)"));
+    }
+
+    @Test
+    public void vertxHttpCustomVertxOptionsShouldSucceed() {
+        RestAssured
+                .given()
+                .queryParam("test-port", RestAssured.port)
+                .when()
+                .get("/test/client/vertx-http/custom-vertx-options")
+                .then()
+                .statusCode(200)
+                .body(is("OK: the custom vertxOptions has triggered the 
expected exception"));
+    }
+
+    @Test
+    public void vertxHttpSessionManagementShouldReturnSecretContent() {
+        RestAssured
+                .given()
+                .queryParam("test-port", RestAssured.port)
+                .when()
+                .get("/test/client/vertx-http/session-management")
+                .then()
+                .statusCode(200)
+                .body(is("Some secret content"));
+    }
+
+    @Test
+    public void vertxHttpBufferConversionWithCharset() {
+        byte[] actualBytes = RestAssured
+                .given()
+                .queryParam("string", "special char €")
+                .queryParam("charset", "iso-8859-15")
+                .when()
+                .get("/test/client/vertx-http/buffer-conversion-with-charset")
+                .then()
+                .statusCode(200)
+                .extract().asByteArray();
+
+        byte[] expectedBytes = new byte[] { 115, 112, 101, 99, 105, 97, 108, 
32, 99, 104, 97, 114, 32, -92 };
+        assertArrayEquals(expectedBytes, actualBytes);
+    }
+
     private Integer getPort() {
         return getPort("camel.netty-http.test-port");
     }

Reply via email to