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

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 3a9b3a2  CAMEL-16220: camel-vertx-http - optimize producer when 
sending to uri without any change
3a9b3a2 is described below

commit 3a9b3a2f65f8734533ed73e588e4ec84f4b728aa
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Wed Feb 17 08:17:13 2021 +0100

    CAMEL-16220: camel-vertx-http - optimize producer when sending to uri 
without any change
---
 .../vertx/http/DefaultVertxHttpBinding.java        | 51 ++++++++++------
 .../component/vertx/http/VertxHttpHelper.java      | 24 ++------
 .../component/vertx/http/VertxHttpProducer.java    | 24 ++++----
 .../vertx/http/VertxHttpProducerLoadTest.java      | 67 ++++++++--------------
 4 files changed, 75 insertions(+), 91 deletions(-)

diff --git 
a/components/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/DefaultVertxHttpBinding.java
 
b/components/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/DefaultVertxHttpBinding.java
index 8c955b5..959486e 100644
--- 
a/components/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/DefaultVertxHttpBinding.java
+++ 
b/components/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/DefaultVertxHttpBinding.java
@@ -21,6 +21,7 @@ import java.net.URI;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Consumer;
 
 import io.vertx.core.AsyncResult;
 import io.vertx.core.MultiMap;
@@ -44,6 +45,8 @@ import static 
org.apache.camel.component.vertx.http.VertxHttpConstants.CONTENT_T
 
 public class DefaultVertxHttpBinding implements VertxHttpBinding {
 
+    private volatile Map<String, Object> defaultQueryParams;
+
     @Override
     public HttpRequest<Buffer> prepareHttpRequest(VertxHttpEndpoint endpoint, 
Exchange exchange) throws Exception {
         VertxHttpConfiguration configuration = endpoint.getConfiguration();
@@ -51,8 +54,14 @@ public class DefaultVertxHttpBinding implements 
VertxHttpBinding {
 
         // Resolve query string from the HTTP_QUERY header or default to those 
provided on the endpoint HTTP URI
         String queryString = VertxHttpHelper.resolveQueryString(exchange);
+        Map<String, Object> queryParams = null;
         if (ObjectHelper.isEmpty(queryString)) {
+            // use default query string from endpoint configuration
             queryString = configuration.getHttpUri().getQuery();
+            if (defaultQueryParams == null) {
+                defaultQueryParams = URISupport.parseQuery(queryString);
+            }
+            queryParams = defaultQueryParams;
         }
 
         // Determine the HTTP method to use if not specified in the 
HTTP_METHOD header
@@ -83,7 +92,9 @@ public class DefaultVertxHttpBinding implements 
VertxHttpBinding {
 
         // Configure query params
         if (ObjectHelper.isNotEmpty(queryString)) {
-            Map<String, Object> queryParams = 
URISupport.parseQuery(queryString);
+            if (queryParams == null) {
+                queryParams = URISupport.parseQuery(queryString);
+            }
             for (Map.Entry<String, Object> entry : queryParams.entrySet()) {
                 request.addQueryParam(entry.getKey(), 
entry.getValue().toString());
             }
@@ -111,10 +122,13 @@ public class DefaultVertxHttpBinding implements 
VertxHttpBinding {
 
     @Override
     public void populateRequestHeaders(Exchange exchange, HttpRequest<Buffer> 
request, HeaderFilterStrategy strategy) {
+        // optimize to use add on MultiMap as putHeader on request does a 
remove/add
+        MultiMap headers = request.headers();
+
         // Ensure the Content-Type header is always added if the corresponding 
exchange header is present
         String contentType = ExchangeHelper.getContentType(exchange);
         if (ObjectHelper.isNotEmpty(contentType)) {
-            request.putHeader(Exchange.CONTENT_TYPE, contentType);
+            headers.add(Exchange.CONTENT_TYPE, contentType);
         }
 
         // Transfer exchange headers to the HTTP request while applying the 
filter strategy
@@ -125,7 +139,7 @@ public class DefaultVertxHttpBinding implements 
VertxHttpBinding {
                 Object headerValue = entry.getValue();
                 if (!strategy.applyFilterToCamelHeaders(key, headerValue, 
exchange)) {
                     String str = tc.convertTo(String.class, headerValue);
-                    request.putHeader(key, str);
+                    headers.add(key, str);
                 }
             }
         }
@@ -157,21 +171,24 @@ public class DefaultVertxHttpBinding implements 
VertxHttpBinding {
         message.setHeader(Exchange.HTTP_RESPONSE_TEXT, 
response.statusMessage());
 
         MultiMap headers = response.headers();
+        headers.forEach(new Consumer<Map.Entry<String, String>>() {
+            boolean found = false;
 
-        boolean found = false;
-        for (String headerName : headers.names()) {
-            String name = headerName;
-            String value = headers.get(headerName);
-            if (!found && name.equalsIgnoreCase("content-type")) {
-                found = true;
-                name = Exchange.CONTENT_TYPE;
-                exchange.setProperty(Exchange.CHARSET_NAME, 
IOHelper.getCharsetNameFromContentType(value));
-            }
-            Object extracted = HttpHelper.extractHttpParameterValue(value);
-            if (strategy != null && 
!strategy.applyFilterToExternalHeaders(name, extracted, exchange)) {
-                HttpHelper.appendHeader(message.getHeaders(), name, extracted);
+            @Override
+            public void accept(Map.Entry<String, String> entry) {
+                String name = entry.getKey();
+                String value = entry.getValue();
+                if (!found && name.equalsIgnoreCase("content-type")) {
+                    found = true;
+                    name = Exchange.CONTENT_TYPE;
+                    exchange.setProperty(Exchange.CHARSET_NAME, 
IOHelper.getCharsetNameFromContentType(value));
+                }
+                Object extracted = HttpHelper.extractHttpParameterValue(value);
+                if (strategy != null && 
!strategy.applyFilterToExternalHeaders(name, extracted, exchange)) {
+                    HttpHelper.appendHeader(message.getHeaders(), name, 
extracted);
+                }
             }
-        }
+        });
     }
 
     @Override
@@ -181,7 +198,7 @@ public class DefaultVertxHttpBinding implements 
VertxHttpBinding {
         Buffer responseBody = result.body();
         if (responseBody != null) {
             String contentType = result.getHeader(Exchange.CONTENT_TYPE);
-            if 
(VertxHttpHelper.isContentTypeMatching(CONTENT_TYPE_JAVA_SERIALIZED_OBJECT, 
contentType)) {
+            if (CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType)) {
                 boolean transferException = 
endpoint.getConfiguration().isTransferException();
                 boolean allowJavaSerializedObject = 
endpoint.getComponent().isAllowJavaSerializedObject();
 
diff --git 
a/components/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHelper.java
 
b/components/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHelper.java
index 43b3e9a..ecb2f52 100644
--- 
a/components/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHelper.java
+++ 
b/components/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHelper.java
@@ -34,7 +34,6 @@ import io.vertx.core.net.TCPSSLOptions;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
 import org.apache.camel.http.base.HttpHelper;
-import org.apache.camel.support.ExchangeHelper;
 import org.apache.camel.support.jsse.KeyManagersParameters;
 import org.apache.camel.support.jsse.SSLContextParameters;
 import org.apache.camel.support.jsse.TrustManagersParameters;
@@ -129,27 +128,16 @@ public final class VertxHttpHelper {
     }
 
     /**
-     * Verifies whether the Content-Type exchange header value matches an 
expected value
-     */
-    public static boolean isContentTypeMatching(Exchange exchange, String 
expected) {
-        return isContentTypeMatching(expected, 
ExchangeHelper.getContentType(exchange));
-    }
-
-    /**
-     * Verifies whether the expected Content-Type value matches an expected 
value
-     */
-    public static boolean isContentTypeMatching(String expected, String 
actual) {
-        return actual != null && expected.equals(actual);
-    }
-
-    /**
      * Writes the given target object to an {@link ObjectOutputStream}
      */
     public static void writeObjectToStream(OutputStream stream, Object target) 
throws IOException {
         ObjectOutputStream oos = new ObjectOutputStream(stream);
-        oos.writeObject(target);
-        oos.flush();
-        IOHelper.close(oos);
+        try {
+            oos.writeObject(target);
+            oos.flush();
+        } finally {
+            IOHelper.close(oos);
+        }
     }
 
     /**
diff --git 
a/components/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpProducer.java
 
b/components/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpProducer.java
index 51e7412..e5a7df4 100644
--- 
a/components/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpProducer.java
+++ 
b/components/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpProducer.java
@@ -33,7 +33,7 @@ import org.apache.camel.CamelExchangeException;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
 import org.apache.camel.support.DefaultAsyncProducer;
-import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.support.MessageHelper;
 import org.apache.camel.util.URISupport;
 
 import static 
org.apache.camel.component.vertx.http.VertxHttpConstants.CONTENT_TYPE_FORM_URLENCODED;
@@ -41,8 +41,11 @@ import static 
org.apache.camel.component.vertx.http.VertxHttpConstants.CONTENT_T
 
 public class VertxHttpProducer extends DefaultAsyncProducer {
 
+    private final VertxHttpBinding vertxHttpBinding;
+
     public VertxHttpProducer(VertxHttpEndpoint endpoint) {
         super(endpoint);
+        this.vertxHttpBinding = 
endpoint.getConfiguration().getVertxHttpBinding();
     }
 
     @Override
@@ -59,7 +62,6 @@ public class VertxHttpProducer extends DefaultAsyncProducer {
         Message message = exchange.getMessage();
 
         try {
-            VertxHttpBinding vertxHttpBinding = 
getEndpoint().getConfiguration().getVertxHttpBinding();
             HttpRequest<Buffer> request = 
vertxHttpBinding.prepareHttpRequest(getEndpoint(), exchange);
             Handler<AsyncResult<HttpResponse<Buffer>>> resultHandler = 
createResultHandler(exchange, callback);
 
@@ -67,6 +69,8 @@ public class VertxHttpProducer extends DefaultAsyncProducer {
             if (body == null) {
                 request.send(resultHandler);
             } else {
+                String contentType = MessageHelper.getContentType(message);
+
                 // Handle the request body payload
                 if (body instanceof MultiMap) {
                     request.sendForm((MultiMap) body, resultHandler);
@@ -76,27 +80,21 @@ public class VertxHttpProducer extends DefaultAsyncProducer 
{
                     request.sendStream((ReadStream<Buffer>) body, 
resultHandler);
                 } else if (body instanceof String) {
                     // Try to extract URL encoded form data from the message 
body
-                    if (VertxHttpHelper.isContentTypeMatching(exchange, 
CONTENT_TYPE_FORM_URLENCODED)) {
+                    if (CONTENT_TYPE_FORM_URLENCODED.equals(contentType)) {
                         MultiMap map = MultiMap.caseInsensitiveMultiMap();
                         Map<String, Object> formParams = 
URISupport.parseQuery((String) body);
                         formParams.keySet().forEach(key -> map.add(key, 
String.valueOf(formParams.get(key))));
                         request.sendForm(map, resultHandler);
                     } else {
                         // Fallback to send as Buffer
-                        Buffer buffer;
-                        String charset = 
VertxHttpHelper.getCharsetFromExchange(exchange);
-                        if (ObjectHelper.isNotEmpty(charset)) {
-                            buffer = Buffer.buffer((String) body, charset);
-                        } else {
-                            buffer = Buffer.buffer((String) body);
-                        }
+                        Buffer buffer = VertxBufferConverter.toBuffer((String) 
body, exchange);
                         request.sendBuffer(buffer, resultHandler);
                     }
                 } else if (body instanceof Buffer) {
                     request.sendBuffer((Buffer) body, resultHandler);
                 } else {
                     // Handle x-java-serialized-object Content-Type
-                    if (VertxHttpHelper.isContentTypeMatching(exchange, 
CONTENT_TYPE_JAVA_SERIALIZED_OBJECT)) {
+                    if 
(CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType)) {
                         if (!getComponent().isAllowJavaSerializedObject()) {
                             throw new CamelExchangeException(
                                     "Content-type " + 
CONTENT_TYPE_JAVA_SERIALIZED_OBJECT + " is not allowed", exchange);
@@ -126,9 +124,7 @@ public class VertxHttpProducer extends DefaultAsyncProducer 
{
     private Handler<AsyncResult<HttpResponse<Buffer>>> 
createResultHandler(Exchange exchange, AsyncCallback callback) {
         return response -> {
             try {
-                VertxHttpEndpoint endpoint = getEndpoint();
-                VertxHttpBinding vertxHttpBinding = 
endpoint.getConfiguration().getVertxHttpBinding();
-                vertxHttpBinding.handleResponse(endpoint, exchange, response);
+                vertxHttpBinding.handleResponse(getEndpoint(), exchange, 
response);
             } catch (Exception e) {
                 exchange.setException(e);
             } finally {
diff --git 
a/components/camel-vertx-http/src/test/java/org/apache/camel/component/vertx/http/VertxHttpProducerLoadTest.java
 
b/components/camel-vertx-http/src/test/java/org/apache/camel/component/vertx/http/VertxHttpProducerLoadTest.java
index 670e076..18701e13 100644
--- 
a/components/camel-vertx-http/src/test/java/org/apache/camel/component/vertx/http/VertxHttpProducerLoadTest.java
+++ 
b/components/camel-vertx-http/src/test/java/org/apache/camel/component/vertx/http/VertxHttpProducerLoadTest.java
@@ -16,6 +16,12 @@
  */
 package org.apache.camel.component.vertx.http;
 
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.Producer;
 import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.util.StopWatch;
@@ -46,51 +52,28 @@ public class VertxHttpProducerLoadTest extends 
VertxHttpTestSupport {
 
     @Test
     public void testProducerLoad() throws Exception {
+        Map<String, Object> map = new HashMap<>();
+        for (int i = 0; i < 40; i++) {
+            map.put("mykey" + i, "myvalue" + i);
+        }
+
         StopWatch watch = new StopWatch();
+
+        // do not use template but reuse exchange/producer to be light-weight
+        // and not create additional objects in the JVM as we want to analyze
+        // the "raw" http producer
+        Endpoint to = getMandatoryEndpoint("direct:echo");
+        Producer producer = to.createProducer();
+        producer.start();
+
+        Exchange exchange = to.createExchange();
+        exchange.getMessage().setHeaders(map);
         for (int i = 0; i < 10000000; i++) {
-            fluentTemplate.to("direct:echo")
-                    .withHeader("a", "aaa")
-                    .withHeader("b", "bbb")
-                    .withHeader("c", "ccc")
-                    .withHeader("d", "ddd")
-                    .withHeader("e", "eee")
-                    .withHeader("f", "fff")
-                    .withHeader("g", "ggg")
-                    .withHeader("h", "hhh")
-                    .withHeader("i", "iii")
-                    .withHeader("j", "jjj")
-                    .withHeader("a2", "aaa")
-                    .withHeader("b2", "bbb")
-                    .withHeader("c2", "ccc")
-                    .withHeader("d2", "ddd")
-                    .withHeader("e2", "eee")
-                    .withHeader("f2", "fff")
-                    .withHeader("g2", "ggg")
-                    .withHeader("h2", "hhh")
-                    .withHeader("i2", "iii")
-                    .withHeader("j2", "jjj")
-                    .withHeader("a3", "aaa")
-                    .withHeader("b3", "bbb")
-                    .withHeader("c3", "ccc")
-                    .withHeader("d3", "ddd")
-                    .withHeader("e3", "eee")
-                    .withHeader("f3", "fff")
-                    .withHeader("g3", "ggg")
-                    .withHeader("h3", "hhh")
-                    .withHeader("i3", "iii")
-                    .withHeader("j3", "jjj")
-                    .withHeader("a4", "aaa")
-                    .withHeader("b4", "bbb")
-                    .withHeader("c4", "ccc")
-                    .withHeader("d4", "ddd")
-                    .withHeader("e4", "eee")
-                    .withHeader("f4", "fff")
-                    .withHeader("g4", "ggg")
-                    .withHeader("h4", "hhh")
-                    .withHeader("i4", "iii")
-                    .withHeader("j4", "jjj")
-                    .withHeader("myHeader", "msg" + i).send();
+            exchange.getMessage().setBody("Message " + i);
+            producer.process(exchange);
         }
+        producer.stop();
+
         LOG.info("Took {} ms", watch.taken());
     }
 

Reply via email to