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 2020/09/27 09:12:34 UTC

[camel] 01/05: CAMEL-14499: Optimize to avoid using camel-core-catalog for SendDynamicAware for camel-file/camel-ftp.

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

commit d06f03e74f013a812ba7e5bf10793e33e711baff
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sat Sep 26 21:48:42 2020 +0200

    CAMEL-14499: Optimize to avoid using camel-core-catalog for SendDynamicAware for camel-file/camel-ftp.
---
 components/camel-file/pom.xml                      |   5 -
 .../file/GenericFileSendDynamicAware.java          |  18 ++--
 .../camel/http/base/HttpSendDynamicAware.java      |  26 +++--
 .../org/apache/camel/spi/SendDynamicAware.java     |  33 +++++--
 .../camel/processor/SendDynamicAwareResolver.java  |   1 +
 .../camel/processor/SendDynamicProcessor.java      |   5 +-
 .../camel/component/bar/BarSendDynamicAware.java   |  17 +++-
 .../support/component/SendDynamicAwareSupport.java | 105 +++++++++++++++++++--
 8 files changed, 158 insertions(+), 52 deletions(-)

diff --git a/components/camel-file/pom.xml b/components/camel-file/pom.xml
index 138ea49..b1f73d3 100644
--- a/components/camel-file/pom.xml
+++ b/components/camel-file/pom.xml
@@ -43,11 +43,6 @@
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-cluster</artifactId>
         </dependency>
-        <!-- needed for dynamic to -->
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-core-catalog</artifactId>
-        </dependency>
 
     </dependencies>
 </project>
diff --git a/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileSendDynamicAware.java b/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileSendDynamicAware.java
index 0c04241..71566b9 100644
--- a/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileSendDynamicAware.java
+++ b/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileSendDynamicAware.java
@@ -16,7 +16,6 @@
  */
 package org.apache.camel.component.file;
 
-import java.util.LinkedHashMap;
 import java.util.Map;
 
 import org.apache.camel.Exchange;
@@ -26,21 +25,19 @@ import org.apache.camel.util.URISupport;
 
 public abstract class GenericFileSendDynamicAware extends SendDynamicAwareSupport {
 
-    private String scheme;
-
     @Override
-    public void setScheme(String scheme) {
-        this.scheme = scheme;
+    public boolean isOnlyDynamicQueryParameters() {
+        return true;
     }
 
     @Override
-    public String getScheme() {
-        return scheme;
+    public boolean isLenientProperties() {
+        return false;
     }
 
     @Override
     public DynamicAwareEntry prepare(Exchange exchange, String uri, String originalUri) throws Exception {
-        Map<String, String> properties = endpointProperties(exchange, uri);
+        Map<String, Object> properties = endpointProperties(exchange, uri);
         return new DynamicAwareEntry(uri, originalUri, properties, null);
     }
 
@@ -56,8 +53,9 @@ public abstract class GenericFileSendDynamicAware extends SendDynamicAwareSuppor
         // if any of the above are in use, then they should not be pre evaluated
         // and we need to rebuild a new uri with them as-is
         if (fileName || tempFileName || idempotentKey || move || moveFailed || preMove || moveExisting) {
-            Map<String, String> params = new LinkedHashMap<>(entry.getProperties());
+            Map<String, Object> params = entry.getProperties();
 
+            // TODO: parseQuery should only have the query part, this is not correct
             Map<String, Object> originalParams = URISupport.parseQuery(entry.getOriginalUri());
             if (fileName) {
                 Object val = originalParams.get("fileName");
@@ -102,7 +100,7 @@ public abstract class GenericFileSendDynamicAware extends SendDynamicAwareSuppor
                 }
             }
 
-            return asEndpointUri(exchange, scheme, params);
+            return asEndpointUri(exchange, entry.getUri(), params);
         } else {
             return entry.getUri();
         }
diff --git a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpSendDynamicAware.java b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpSendDynamicAware.java
index 9892acb..5692ec5 100644
--- a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpSendDynamicAware.java
+++ b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpSendDynamicAware.java
@@ -38,22 +38,20 @@ public class HttpSendDynamicAware extends SendDynamicAwareSupport {
 
     private final Processor postProcessor = new HttpSendDynamicPostProcessor();
 
-    private String scheme;
-
     @Override
-    public void setScheme(String scheme) {
-        this.scheme = scheme;
+    public boolean isOnlyDynamicQueryParameters() {
+        return false;
     }
 
     @Override
-    public String getScheme() {
-        return scheme;
+    public boolean isLenientProperties() {
+        return true;
     }
 
     @Override
     public DynamicAwareEntry prepare(Exchange exchange, String uri, String originalUri) throws Exception {
-        Map<String, String> properties = endpointProperties(exchange, uri);
-        Map<String, String> lenient = endpointLenientProperties(exchange, uri);
+        Map<String, Object> properties = endpointProperties(exchange, uri);
+        Map<String, Object> lenient = endpointLenientProperties(exchange, uri);
         return new DynamicAwareEntry(uri, originalUri, properties, lenient);
     }
 
@@ -65,7 +63,7 @@ public class HttpSendDynamicAware extends SendDynamicAwareSupport {
         if (path != null || !entry.getLenientProperties().isEmpty()) {
             // the context path can be dynamic or any lenient properties
             // and therefore build a new static uri without path or lenient options
-            Map<String, String> params = new LinkedHashMap<>(entry.getProperties());
+            Map<String, Object> params = entry.getProperties();
             for (String k : entry.getLenientProperties().keySet()) {
                 params.remove(k);
             }
@@ -75,12 +73,12 @@ public class HttpSendDynamicAware extends SendDynamicAwareSupport {
                     params.put("httpUri", host);
                 } else if (params.containsKey("httpURI")) {
                     params.put("httpURI", host);
-                } else if ("netty-http".equals(scheme)) {
+                } else if ("netty-http".equals(getScheme())) {
                     // the netty-http stores host,port etc in other fields than httpURI so we can just remove the path parameter
                     params.remove("path");
                 }
             }
-            return asEndpointUri(exchange, scheme, params);
+            return asEndpointUri(exchange, entry.getUri(), params);
         } else {
             // no need for optimisation
             return null;
@@ -118,10 +116,10 @@ public class HttpSendDynamicAware extends SendDynamicAwareSupport {
         String u = entry.getUri();
 
         // remove scheme prefix (unless its camel-http or camel-http)
-        boolean httpComponent = "http".equals(scheme) || "https".equals(scheme);
+        boolean httpComponent = "http".equals(getScheme()) || "https".equals(getScheme());
         if (!httpComponent) {
-            String prefix = scheme + "://";
-            String prefix2 = scheme + ":";
+            String prefix = getScheme() + "://";
+            String prefix2 = getScheme() + ":";
             if (u.startsWith(prefix)) {
                 u = u.substring(prefix.length());
             } else if (u.startsWith(prefix2)) {
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/SendDynamicAware.java b/core/camel-api/src/main/java/org/apache/camel/spi/SendDynamicAware.java
index 2efb5f0..c07ec4a 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/SendDynamicAware.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/SendDynamicAware.java
@@ -18,16 +18,19 @@ package org.apache.camel.spi;
 
 import java.util.Map;
 
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.Service;
 
 /**
  * Used for components that can optimise the usage of {@link org.apache.camel.processor.SendDynamicProcessor} (toD) to
  * reuse a static {@link org.apache.camel.Endpoint} and {@link Producer} that supports using headers to provide the
  * dynamic parts. For example many of the HTTP components supports this.
  */
-public interface SendDynamicAware {
+public interface SendDynamicAware extends Service, CamelContextAware {
 
     /**
      * Sets the component name.
@@ -42,6 +45,22 @@ public interface SendDynamicAware {
     String getScheme();
 
     /**
+     * Whether only the query parameters can be dynamic and the context-path must be static.
+     *
+     * If true then Camel can restructure endpoint uri using a simple and faster parser.
+     * On the other hand if the context-path and authority part of the URI can be dynamic
+     * then Camel has to use a more complex and slower parser.
+     */
+    boolean isOnlyDynamicQueryParameters();
+
+    /**
+     * Whether the endpoint is lenient or not.
+     *
+     * @see Endpoint#isLenientProperties()
+     */
+    boolean isLenientProperties();
+
+    /**
      * An entry of detailed information from the recipient uri, which allows the {@link SendDynamicAware} implementation
      * to prepare pre- and post- processor and the static uri to be used for the optimised dynamic to.
      */
@@ -49,11 +68,11 @@ public interface SendDynamicAware {
 
         private final String uri;
         private final String originalUri;
-        private final Map<String, String> properties;
-        private final Map<String, String> lenientProperties;
+        private final Map<String, Object> properties;
+        private final Map<String, Object> lenientProperties;
 
-        public DynamicAwareEntry(String uri, String originalUri, Map<String, String> properties,
-                                 Map<String, String> lenientProperties) {
+        public DynamicAwareEntry(String uri, String originalUri, Map<String, Object> properties,
+                                 Map<String, Object> lenientProperties) {
             this.uri = uri;
             this.originalUri = originalUri;
             this.properties = properties;
@@ -68,11 +87,11 @@ public interface SendDynamicAware {
             return originalUri;
         }
 
-        public Map<String, String> getProperties() {
+        public Map<String, Object> getProperties() {
             return properties;
         }
 
-        public Map<String, String> getLenientProperties() {
+        public Map<String, Object> getLenientProperties() {
             return lenientProperties;
         }
     }
diff --git a/core/camel-base/src/main/java/org/apache/camel/processor/SendDynamicAwareResolver.java b/core/camel-base/src/main/java/org/apache/camel/processor/SendDynamicAwareResolver.java
index 6bbefea..8ee8b0c 100644
--- a/core/camel-base/src/main/java/org/apache/camel/processor/SendDynamicAwareResolver.java
+++ b/core/camel-base/src/main/java/org/apache/camel/processor/SendDynamicAwareResolver.java
@@ -51,6 +51,7 @@ public class SendDynamicAwareResolver {
             if (SendDynamicAware.class.isAssignableFrom(type)) {
                 SendDynamicAware answer = (SendDynamicAware) context.getInjector().newInstance(type, false);
                 answer.setScheme(scheme);
+                answer.setCamelContext(context);
                 return answer;
             } else {
                 throw new IllegalArgumentException("Type is not a SendDynamicAware implementation. Found: " + type.getName());
diff --git a/core/camel-base/src/main/java/org/apache/camel/processor/SendDynamicProcessor.java b/core/camel-base/src/main/java/org/apache/camel/processor/SendDynamicProcessor.java
index 118aee1..2ce3ede 100644
--- a/core/camel-base/src/main/java/org/apache/camel/processor/SendDynamicProcessor.java
+++ b/core/camel-base/src/main/java/org/apache/camel/processor/SendDynamicProcessor.java
@@ -336,6 +336,7 @@ public class SendDynamicProcessor extends AsyncProcessorSupport implements IdAwa
                 }
             }
         }
+        ServiceHelper.initService(dynamicAware);
     }
 
     @Override
@@ -355,12 +356,12 @@ public class SendDynamicProcessor extends AsyncProcessorSupport implements IdAwa
             }
         }
 
-        ServiceHelper.startService(producerCache);
+        ServiceHelper.startService(dynamicAware, producerCache);
     }
 
     @Override
     protected void doStop() throws Exception {
-        ServiceHelper.stopService(producerCache);
+        ServiceHelper.stopService(producerCache, dynamicAware);
     }
 
     public EndpointUtilizationStatistics getEndpointUtilizationStatistics() {
diff --git a/core/camel-core/src/test/java/org/apache/camel/component/bar/BarSendDynamicAware.java b/core/camel-core/src/test/java/org/apache/camel/component/bar/BarSendDynamicAware.java
index 2b81589..a044830 100644
--- a/core/camel-core/src/test/java/org/apache/camel/component/bar/BarSendDynamicAware.java
+++ b/core/camel-core/src/test/java/org/apache/camel/component/bar/BarSendDynamicAware.java
@@ -16,7 +16,6 @@
  */
 package org.apache.camel.component.bar;
 
-import java.util.LinkedHashMap;
 import java.util.Map;
 
 import org.apache.camel.Exchange;
@@ -24,11 +23,11 @@ import org.apache.camel.Processor;
 import org.apache.camel.builder.ExpressionBuilder;
 import org.apache.camel.processor.RemoveHeaderProcessor;
 import org.apache.camel.processor.SetHeaderProcessor;
-import org.apache.camel.spi.SendDynamicAware;
+import org.apache.camel.support.component.SendDynamicAwareSupport;
 import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.URISupport;
 
-public class BarSendDynamicAware implements SendDynamicAware {
+public class BarSendDynamicAware extends SendDynamicAwareSupport {
 
     private String scheme;
 
@@ -43,10 +42,20 @@ public class BarSendDynamicAware implements SendDynamicAware {
     }
 
     @Override
+    public boolean isOnlyDynamicQueryParameters() {
+        return false;
+    }
+
+    @Override
+    public boolean isLenientProperties() {
+        return false;
+    }
+
+    @Override
     public DynamicAwareEntry prepare(Exchange exchange, String uri, String originalUri) throws Exception {
         String query = StringHelper.after(uri, "?");
         if (query != null) {
-            Map<String, String> map = new LinkedHashMap(URISupport.parseQuery(query));
+            Map<String, Object> map = URISupport.parseQuery(query);
             return new DynamicAwareEntry(uri, originalUri, map, null);
         } else {
             return new DynamicAwareEntry(uri, originalUri, null, null);
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/component/SendDynamicAwareSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/component/SendDynamicAwareSupport.java
index 12262db..485e7a4 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/component/SendDynamicAwareSupport.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/component/SendDynamicAwareSupport.java
@@ -16,32 +16,117 @@
  */
 package org.apache.camel.support.component;
 
+import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Set;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.catalog.RuntimeCamelCatalog;
 import org.apache.camel.spi.SendDynamicAware;
+import org.apache.camel.support.service.ServiceSupport;
+import org.apache.camel.util.URISupport;
 
 /**
  * Support class for {@link SendDynamicAware} implementations.
  */
-public abstract class SendDynamicAwareSupport implements SendDynamicAware {
+public abstract class SendDynamicAwareSupport extends ServiceSupport implements SendDynamicAware {
 
-    public Map<String, String> endpointProperties(Exchange exchange, String uri) throws Exception {
-        RuntimeCamelCatalog catalog = exchange.getContext().adapt(ExtendedCamelContext.class).getRuntimeCamelCatalog();
-        Map<String, String> properties = catalog.endpointProperties(uri);
+    private CamelContext camelContext;
+    private Set<String> knownProperties;
+    private String scheme;
+
+    @Override
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    @Override
+    public void setScheme(String scheme) {
+        this.scheme = scheme;
+    }
+
+    @Override
+    public String getScheme() {
+        return scheme;
+    }
+
+    @Override
+    protected void doInit() throws Exception {
+        if (isOnlyDynamicQueryParameters()) {
+            knownProperties = getCamelContext().adapt(ExtendedCamelContext.class).getEndpointUriFactory(getScheme()).propertyNames();
+        }
+    }
+
+    public Map<String, Object> endpointProperties(Exchange exchange, String uri) throws Exception {
+        Map<String, Object> properties;
+        if (isOnlyDynamicQueryParameters()) {
+            // optimize as we know its only query parameters that can be dynamic, and that there are no lenient properties
+            Map<String, Object> map;
+            int pos = uri.indexOf('?');
+            if (pos != -1) {
+                String query = uri.substring(pos + 1);
+                map = URISupport.parseQuery(query);
+            } else {
+                map = Collections.EMPTY_MAP;
+            }
+            if (map != null && isLenientProperties()) {
+                properties = new LinkedHashMap<>(map.size());
+                // okay so only add the known properties as they are the non lenient properties
+                map.forEach((k, v) -> {
+                    if (knownProperties.contains(k)) {
+                        properties.put(k, v);
+                    }
+                });
+            } else {
+                properties = map;
+            }
+        } else {
+            RuntimeCamelCatalog catalog = exchange.getContext().adapt(ExtendedCamelContext.class).getRuntimeCamelCatalog();
+            properties = new LinkedHashMap<>(catalog.endpointProperties(uri));
+        }
         return properties;
     }
 
-    public Map<String, String> endpointLenientProperties(Exchange exchange, String uri) throws Exception {
-        RuntimeCamelCatalog catalog = exchange.getContext().adapt(ExtendedCamelContext.class).getRuntimeCamelCatalog();
-        Map<String, String> properties = catalog.endpointLenientProperties(uri);
+    public Map<String, Object> endpointLenientProperties(Exchange exchange, String uri) throws Exception {
+        Map<String, Object> properties;
+        if (isOnlyDynamicQueryParameters()) {
+            // optimize as we know its only query parameters that can be dynamic
+            Map<String, Object> map  = URISupport.parseQuery(uri);
+            properties = new LinkedHashMap<>();
+            map.forEach((k, v) -> {
+                if (!knownProperties.contains(k)) {
+                    properties.put(k, v.toString());
+                }
+            });
+        } else {
+            RuntimeCamelCatalog catalog = exchange.getContext().adapt(ExtendedCamelContext.class).getRuntimeCamelCatalog();
+            properties = new LinkedHashMap<>(catalog.endpointLenientProperties(uri));
+        }
         return properties;
     }
 
-    public String asEndpointUri(Exchange exchange, String scheme, Map<String, String> properties) throws Exception {
-        RuntimeCamelCatalog catalog = exchange.getContext().adapt(ExtendedCamelContext.class).getRuntimeCamelCatalog();
-        return catalog.asEndpointUri(scheme, properties, false);
+    public String asEndpointUri(Exchange exchange, String uri, Map<String, Object> properties) throws Exception {
+        if (isOnlyDynamicQueryParameters()) {
+            String answer;
+            String query = URISupport.createQueryString(properties, false);
+            int pos = uri.indexOf('?');
+            if (pos != -1) {
+                answer = uri.substring(0, pos) + "?" + query;
+            } else {
+                answer = uri + "?" + query;
+            }
+            return answer;
+        } else {
+            RuntimeCamelCatalog catalog = exchange.getContext().adapt(ExtendedCamelContext.class).getRuntimeCamelCatalog();
+            return catalog.asEndpointUri(getScheme(), new LinkedHashMap(properties), false);
+        }
     }
 }