You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/10/17 19:39:48 UTC
[camel] branch main updated: CAMEL-19994: camel-platform-http-vertx - Allow access to vertx request object. Add support for pooled exchange like we have in other http components. (#11739)
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new fb21cbd87ac CAMEL-19994: camel-platform-http-vertx - Allow access to vertx request object. Add support for pooled exchange like we have in other http components. (#11739)
fb21cbd87ac is described below
commit fb21cbd87ac6b01a3d74fd4c6685798f9a594b06
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Oct 17 21:39:41 2023 +0200
CAMEL-19994: camel-platform-http-vertx - Allow access to vertx request object. Add support for pooled exchange like we have in other http components. (#11739)
---
components/camel-platform-http-vertx/pom.xml | 6 +
.../src/main/docs/platform-http-vertx.adoc | 20 ++++
.../component/platform/http/vertx/HttpMessage.java | 66 +++++++++++
.../http/vertx/VertxPlatformHttpConsumer.java | 16 ++-
.../http/vertx/VertxPlatformHttpEngineTest.java | 30 +++++
.../vertx/VertxPlatformHttpPooledExchangeTest.java | 126 +++++++++++++++++++++
6 files changed, 259 insertions(+), 5 deletions(-)
diff --git a/components/camel-platform-http-vertx/pom.xml b/components/camel-platform-http-vertx/pom.xml
index ec47987865f..200bdc6cd3c 100644
--- a/components/camel-platform-http-vertx/pom.xml
+++ b/components/camel-platform-http-vertx/pom.xml
@@ -108,6 +108,12 @@
<version>${wiremock-version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.awaitility</groupId>
+ <artifactId>awaitility</artifactId>
+ <version>${awaitility-version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/components/camel-platform-http-vertx/src/main/docs/platform-http-vertx.adoc b/components/camel-platform-http-vertx/src/main/docs/platform-http-vertx.adoc
index e4f7ac16dfb..118225964ff 100644
--- a/components/camel-platform-http-vertx/src/main/docs/platform-http-vertx.adoc
+++ b/components/camel-platform-http-vertx/src/main/docs/platform-http-vertx.adoc
@@ -76,3 +76,23 @@ from("platform-http:proxy")
.toD("http://"
+ "${headers." + Exchange.HTTP_HOST + "}");
----
+
+== Access to Request and Response
+
+The Vertx HTTP server has its own API abstraction for HTTP request/response objects which you can access via
+Camel `HttpMessage` as shown in the custom `Processor` below :
+
+[source,java]
+----
+.process(exchange -> {
+ // grab message as HttpMessage
+ HttpMessage message = exchange.getMessage(HttpMessage.class);
+ // use getRequest() / getResponse() to access Vertx directly
+ // you can add custom headers
+ message.getResponse().putHeader("beer", "Heineken");
+ // also access request details and use that in the code
+ String p = message.getRequest().path();
+ message.setBody("request path: " + p);
+});
+----
+
diff --git a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/HttpMessage.java b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/HttpMessage.java
new file mode 100644
index 00000000000..cece097b89c
--- /dev/null
+++ b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/HttpMessage.java
@@ -0,0 +1,66 @@
+/*
+ * 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.vertx;
+
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.core.http.HttpServerResponse;
+import org.apache.camel.Exchange;
+import org.apache.camel.support.DefaultMessage;
+import org.apache.camel.util.ObjectHelper;
+
+public class HttpMessage extends DefaultMessage {
+
+ private HttpServerRequest request;
+ private HttpServerResponse response;
+
+ public HttpMessage(Exchange exchange, HttpServerRequest request, HttpServerResponse response) {
+ super(exchange);
+ init(exchange, request, response);
+ }
+
+ public void init(Exchange exchange, HttpServerRequest request, HttpServerResponse response) {
+ setExchange(exchange);
+ this.request = request;
+ this.response = response;
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ request = null;
+ response = null;
+ }
+
+ public HttpServerRequest getRequest() {
+ return request;
+ }
+
+ public HttpServerResponse getResponse() {
+ return response;
+ }
+
+ @Override
+ public HttpMessage newInstance() {
+ return new HttpMessage(getExchange(), request, response);
+ }
+
+ @Override
+ public String toString() {
+ // do not use toString on HTTP message
+ return "HttpMessage@" + ObjectHelper.getIdentityHashCode(this);
+ }
+}
diff --git a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java
index 4ab809ec411..4b96d86c504 100644
--- a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java
+++ b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java
@@ -230,7 +230,16 @@ public class VertxPlatformHttpConsumer extends DefaultConsumer implements Suspen
final Exchange exchange = createExchange(false);
exchange.setPattern(ExchangePattern.InOut);
- final Message in = toCamelMessage(ctx, exchange);
+ // reuse existing http message if pooled
+ Message in = exchange.getIn();
+ if (in instanceof HttpMessage hm) {
+ hm.init(exchange, ctx.request(), ctx.response());
+ } else {
+ in = new HttpMessage(exchange, ctx.request(), ctx.response());
+ exchange.setMessage(in);
+ }
+ populateCamelMessage(ctx, exchange, in);
+
final String charset = ctx.parsedHeaders().contentType().parameter("charset");
if (charset != null) {
exchange.setProperty(ExchangePropertyKey.CHARSET_NAME, charset);
@@ -245,9 +254,7 @@ public class VertxPlatformHttpConsumer extends DefaultConsumer implements Suspen
return exchange;
}
- protected Message toCamelMessage(RoutingContext ctx, Exchange exchange) {
- final Message result = exchange.getIn();
-
+ protected void populateCamelMessage(RoutingContext ctx, Exchange exchange, Message result) {
final HeaderFilterStrategy headerFilterStrategy = getEndpoint().getHeaderFilterStrategy();
populateCamelHeaders(ctx, result.getHeaders(), exchange, headerFilterStrategy);
final String mimeType = ctx.parsedHeaders().contentType().value();
@@ -281,7 +288,6 @@ public class VertxPlatformHttpConsumer extends DefaultConsumer implements Suspen
result.setBody(null);
}
}
- return result;
}
protected void populateAttachments(List<FileUpload> uploads, Message message) {
diff --git a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
index 683b2327e1d..633826ad959 100644
--- a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
+++ b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
@@ -846,6 +846,36 @@ public class VertxPlatformHttpEngineTest {
}
}
+ @Test
+ public void testVertxRequestResponseObjects() throws Exception {
+ final CamelContext context = createCamelContext();
+
+ try {
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("platform-http:/vertx/objects")
+ .process(exchange -> {
+ HttpMessage message = exchange.getMessage(HttpMessage.class);
+ String p = message.getRequest().path();
+ message.getResponse().putHeader("beer", "Heineken");
+ message.setBody("request path: " + p);
+ });
+ }
+ });
+
+ context.start();
+
+ get("/vertx/objects")
+ .then()
+ .statusCode(200)
+ .header("beer", "Heineken")
+ .body(is("request path: /vertx/objects"));
+ } finally {
+ context.stop();
+ }
+ }
+
static CamelContext createCamelContext() throws Exception {
return createCamelContext(null);
}
diff --git a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpPooledExchangeTest.java b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpPooledExchangeTest.java
new file mode 100644
index 00000000000..05083e3a2f3
--- /dev/null
+++ b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpPooledExchangeTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.vertx;
+
+import java.util.concurrent.TimeUnit;
+
+import io.restassured.RestAssured;
+import org.apache.camel.CamelContext;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.component.platform.http.PlatformHttpComponent;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.engine.PooledExchangeFactory;
+import org.apache.camel.impl.engine.PooledProcessorExchangeFactory;
+import org.apache.camel.spi.PooledObjectFactory;
+import org.apache.camel.test.AvailablePortFinder;
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.Test;
+
+import static io.restassured.RestAssured.get;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class VertxPlatformHttpPooledExchangeTest {
+
+ @Test
+ public void testEngineSetup() throws Exception {
+ final CamelContext context = createCamelContext();
+ try {
+ context.start();
+
+ assertThat(VertxPlatformHttpRouter.lookup(context)).isNotNull();
+ assertThat(context.getComponent("platform-http")).isInstanceOfSatisfying(PlatformHttpComponent.class, component -> {
+ assertThat(component.getEngine()).isInstanceOf(VertxPlatformHttpEngine.class);
+ });
+
+ } finally {
+ context.stop();
+ }
+ }
+
+ @Test
+ public void testPooledExchange() throws Exception {
+ final CamelContext context = createCamelContext();
+
+ try {
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("platform-http:/vertx/pooled")
+ .transform().simple("Bye World");
+ }
+ });
+
+ context.start();
+
+ for (int i = 0; i < 3; i++) {
+ get("/vertx/pooled")
+ .then()
+ .statusCode(200)
+ .body(is("Bye World"));
+ }
+
+ MockEndpoint.assertIsSatisfied(context);
+
+ Awaitility.waitAtMost(5, TimeUnit.SECONDS).untilAsserted(() -> {
+ PooledObjectFactory.Statistics stat
+ = context.getCamelContextExtension().getExchangeFactoryManager().getStatistics();
+ assertEquals(1, stat.getCreatedCounter());
+ assertEquals(2, stat.getAcquiredCounter());
+ assertEquals(3, stat.getReleasedCounter());
+ assertEquals(0, stat.getDiscardedCounter());
+ });
+ } finally {
+ context.stop();
+ }
+ }
+
+ static CamelContext createCamelContext() throws Exception {
+ return createCamelContext(null);
+ }
+
+ private static CamelContext createCamelContext(ServerConfigurationCustomizer customizer) throws Exception {
+ int port = AvailablePortFinder.getNextAvailable();
+ VertxPlatformHttpServerConfiguration conf = new VertxPlatformHttpServerConfiguration();
+ conf.setBindPort(port);
+
+ RestAssured.port = port;
+
+ if (customizer != null) {
+ customizer.customize(conf);
+ }
+
+ CamelContext context = new DefaultCamelContext();
+ context.addService(new VertxPlatformHttpServer(conf));
+
+ ExtendedCamelContext ecc = context.getCamelContextExtension();
+
+ ecc.setExchangeFactory(new PooledExchangeFactory());
+ ecc.setProcessorExchangeFactory(new PooledProcessorExchangeFactory());
+ ecc.getExchangeFactory().setStatisticsEnabled(true);
+ ecc.getProcessorExchangeFactory().setStatisticsEnabled(true);
+
+ return context;
+ }
+
+ interface ServerConfigurationCustomizer {
+ void customize(VertxPlatformHttpServerConfiguration configuration);
+ }
+}