camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From davscl...@apache.org
Subject [2/3] git commit: CAMEL-6995: Language component should not cache script by default as it can cause side-effects when evaluating next messages. End users can turn this option on to have previous behaivor if their scripts is safe to do so.
Date Thu, 21 Nov 2013 17:02:21 GMT
CAMEL-6995: Language component should not cache script by default as it can cause side-effects
when evaluating next messages. End users can turn this option on to have previous behaivor
if their scripts is safe to do so.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/4116ceac
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/4116ceac
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/4116ceac

Branch: refs/heads/camel-2.12.x
Commit: 4116ceac9bae95c2f1fb88d4eb1adadf6a0a9563
Parents: 9753bbc
Author: Claus Ibsen <davsclaus@apache.org>
Authored: Thu Nov 21 18:03:21 2013 +0100
Committer: Claus Ibsen <davsclaus@apache.org>
Committed: Thu Nov 21 18:03:39 2013 +0100

----------------------------------------------------------------------
 .../component/language/LanguageComponent.java   | 10 ++--
 .../component/language/LanguageEndpoint.java    | 31 +++++++++-
 .../component/language/LanguageProducer.java    | 31 +++++++---
 .../language/LanguageCacheScriptTest.java       | 62 ++++++++++++++++++++
 .../LanguageLoadScriptFromFileCachedTest.java   |  4 +-
 .../language/LanguageNoCacheScriptTest.java     | 62 ++++++++++++++++++++
 6 files changed, 186 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/4116ceac/camel-core/src/main/java/org/apache/camel/component/language/LanguageComponent.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/language/LanguageComponent.java
b/camel-core/src/main/java/org/apache/camel/component/language/LanguageComponent.java
index 10cbced..2127256 100644
--- a/camel-core/src/main/java/org/apache/camel/component/language/LanguageComponent.java
+++ b/camel-core/src/main/java/org/apache/camel/component/language/LanguageComponent.java
@@ -20,7 +20,6 @@ import java.net.URLDecoder;
 import java.util.Map;
 
 import org.apache.camel.Endpoint;
-import org.apache.camel.Expression;
 import org.apache.camel.impl.DefaultComponent;
 import org.apache.camel.spi.Language;
 import org.apache.camel.util.ObjectHelper;
@@ -49,7 +48,6 @@ public class LanguageComponent extends DefaultComponent {
         }
         Language language = getCamelContext().resolveLanguage(name);
 
-        Expression expression = null;
         String resourceUri = null;
         String resource = script;
         if (resource != null) {
@@ -61,10 +59,14 @@ public class LanguageComponent extends DefaultComponent {
                 resourceUri = resource;
             } else {
                 // the script is provided as text in the uri, so decode to utf-8
-                expression = language.createExpression(URLDecoder.decode(script, "UTF-8"));
+                script = URLDecoder.decode(script, "UTF-8");
             }
         }
 
-        return new LanguageEndpoint(uri, this, language, expression, resourceUri);
+        LanguageEndpoint endpoint = new LanguageEndpoint(uri, this, language, null, resourceUri);
+        endpoint.setScript(script);
+        setProperties(endpoint, parameters);
+        return endpoint;
     }
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/4116ceac/camel-core/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java
b/camel-core/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java
index 71d2a29..87454a8 100644
--- a/camel-core/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java
+++ b/camel-core/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java
@@ -27,6 +27,7 @@ import org.apache.camel.Expression;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.api.management.ManagedOperation;
 import org.apache.camel.component.ResourceEndpoint;
 import org.apache.camel.spi.Language;
 import org.apache.camel.spi.UriParam;
@@ -50,6 +51,8 @@ public class LanguageEndpoint extends ResourceEndpoint {
     private boolean transform = true;
     @UriParam
     private boolean contentResolvedFromResource;
+    @UriParam
+    private boolean cacheScript;
 
     public LanguageEndpoint() {
         // enable cache by default
@@ -72,7 +75,7 @@ public class LanguageEndpoint extends ResourceEndpoint {
         }
 
         ObjectHelper.notNull(language, "language", this);
-        if (expression == null && script != null) {
+        if (cacheScript && expression == null && script != null) {
             script = resolveScript(script);
             expression = language.createExpression(script);
         }
@@ -167,6 +170,10 @@ public class LanguageEndpoint extends ResourceEndpoint {
         this.script = script;
     }
 
+    public String getScript() {
+        return script;
+    }
+
     public boolean isContentResolvedFromResource() {
         return contentResolvedFromResource;
     }
@@ -174,4 +181,26 @@ public class LanguageEndpoint extends ResourceEndpoint {
     public void setContentResolvedFromResource(boolean contentResolvedFromResource) {
         this.contentResolvedFromResource = contentResolvedFromResource;
     }
+
+    public boolean isCacheScript() {
+        return cacheScript;
+    }
+
+    /**
+     * Whether to cache the compiled script and reuse
+     * <p/>
+     * Notice reusing the script can cause side effects from processing one Camel
+     * {@link org.apache.camel.Exchange} to the next {@link org.apache.camel.Exchange}.
+     */
+    public void setCacheScript(boolean cacheScript) {
+        this.cacheScript = cacheScript;
+    }
+
+    public void clearContentCache() {
+        super.clearContentCache();
+        // must also clear expression and script
+        expression = null;
+        script = null;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/4116ceac/camel-core/src/main/java/org/apache/camel/component/language/LanguageProducer.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/language/LanguageProducer.java
b/camel-core/src/main/java/org/apache/camel/component/language/LanguageProducer.java
index 76a4aec..2e6a10e 100644
--- a/camel-core/src/main/java/org/apache/camel/component/language/LanguageProducer.java
+++ b/camel-core/src/main/java/org/apache/camel/component/language/LanguageProducer.java
@@ -24,6 +24,7 @@ import org.apache.camel.Expression;
 import org.apache.camel.impl.DefaultProducer;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.ResourceHelper;
 import org.apache.camel.util.ServiceHelper;
 
 /**
@@ -49,27 +50,43 @@ public class LanguageProducer extends DefaultProducer {
             }
         }
         // if not fallback to use expression from endpoint
-        if (exp == null) {
+        if (exp == null && getEndpoint().isCacheScript()) {
             exp = getEndpoint().getExpression();
         }
 
         // fallback and use resource uri from endpoint
         if (exp == null) {
-            if (getEndpoint().getResourceUri() != null) {
-                // load the resource
-                String script;
-                InputStream is = getEndpoint().getResourceAsInputStream();
+            String script = getEndpoint().getScript();
+
+            if (script == null && getEndpoint().getResourceUri() == null) {
+                // no script to execute
+                throw new CamelExchangeException("No script to evaluate", exchange);
+            }
+
+            // the script can be a resource from the endpoint,
+            // or refer to a resource itself
+            // or just be a plain string
+            InputStream is = null;
+            if (script == null) {
+                is = getEndpoint().getResourceAsInputStream();
+            } else if (ResourceHelper.hasScheme(script)) {
+                is = ResourceHelper.resolveMandatoryResourceAsInputStream(getEndpoint().getCamelContext().getClassResolver(),
script);
+            }
+            if (is != null) {
                 try {
                     script = getEndpoint().getCamelContext().getTypeConverter().convertTo(String.class,
exchange, is);
                 } finally {
                     IOHelper.close(is);
                 }
+            }
+
+            if (script != null) {
                 // create the expression from the script
                 exp = getEndpoint().getLanguage().createExpression(script);
                 // expression was resolved from resource
                 getEndpoint().setContentResolvedFromResource(true);
                 // if we cache then set this as expression on endpoint so we don't re-create
it again
-                if (getEndpoint().isContentCache()) {
+                if (getEndpoint().isCacheScript()) {
                     getEndpoint().setExpression(exp);
                 }
             } else {
@@ -85,7 +102,7 @@ public class LanguageProducer extends DefaultProducer {
             result = exp.evaluate(exchange, Object.class);
             log.debug("Evaluated expression as: {} with: {}", result, exchange);
         } finally {
-            if (!getEndpoint().isContentCache()) {
+            if (!getEndpoint().isCacheScript()) {
                 // some languages add themselves as a service which we then need to remove
if we are not cached
                 ServiceHelper.stopService(exp);
                 getEndpoint().getCamelContext().removeService(exp);

http://git-wip-us.apache.org/repos/asf/camel/blob/4116ceac/camel-core/src/test/java/org/apache/camel/component/language/LanguageCacheScriptTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/component/language/LanguageCacheScriptTest.java
b/camel-core/src/test/java/org/apache/camel/component/language/LanguageCacheScriptTest.java
new file mode 100644
index 0000000..404449a
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/component/language/LanguageCacheScriptTest.java
@@ -0,0 +1,62 @@
+/**
+ * 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.language;
+
+import java.net.URLEncoder;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Expression;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * @version 
+ */
+public class LanguageCacheScriptTest extends ContextTestSupport {
+
+    private LanguageEndpoint endpoint;
+
+    public void testCache() throws Exception {
+        getMockEndpoint("mock:result").expectedBodiesReceived("World", "Camel");
+
+        template.sendBody("direct:start", "World");
+        Expression first = endpoint.getExpression();
+
+        template.sendBody("direct:start", "Camel");
+        Expression second = endpoint.getExpression();
+
+        assertMockEndpointsSatisfied();
+
+        assertSame(first, second);
+        assertNotNull(first);
+        assertNotNull(second);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                String script = URLEncoder.encode("Hello ${body}", "UTF-8");
+                endpoint = context.getEndpoint("language:simple:" + script + "?transform=false&cacheScript=true",
LanguageEndpoint.class);
+
+                from("direct:start")
+                    .to(endpoint)
+                    .to("mock:result");
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/4116ceac/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromFileCachedTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromFileCachedTest.java
b/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromFileCachedTest.java
index 54575a9..2cc9bc2 100644
--- a/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromFileCachedTest.java
+++ b/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromFileCachedTest.java
@@ -85,8 +85,8 @@ public class LanguageLoadScriptFromFileCachedTest extends ContextTestSupport
{
 
                 // START SNIPPET: e1
                 from("direct:start")
-                    // use content cache to load the script once and cache it (content cache
is default enabled)
-                    .to("language:simple:file:target/script/myscript.txt?contentCache=true")
+                    // use content cache to load the script once and cache it (content cache
and script cache both enabled)
+                    .to("language:simple:file:target/script/myscript.txt?contentCache=true&cacheScript=true")
                     .to("mock:result");
                 // END SNIPPET: e1
             }

http://git-wip-us.apache.org/repos/asf/camel/blob/4116ceac/camel-core/src/test/java/org/apache/camel/component/language/LanguageNoCacheScriptTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/component/language/LanguageNoCacheScriptTest.java
b/camel-core/src/test/java/org/apache/camel/component/language/LanguageNoCacheScriptTest.java
new file mode 100644
index 0000000..278d3eb
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/component/language/LanguageNoCacheScriptTest.java
@@ -0,0 +1,62 @@
+/**
+ * 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.language;
+
+import java.net.URLEncoder;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Expression;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * @version 
+ */
+public class LanguageNoCacheScriptTest extends ContextTestSupport {
+
+    private LanguageEndpoint endpoint;
+
+    public void testNoCache() throws Exception {
+        getMockEndpoint("mock:result").expectedBodiesReceived("World", "Camel");
+
+        template.sendBody("direct:start", "World");
+        Expression first = endpoint.getExpression();
+
+        template.sendBody("direct:start", "Camel");
+        Expression second = endpoint.getExpression();
+
+        assertMockEndpointsSatisfied();
+
+        assertSame(first, second);
+        assertNull(first);
+        assertNull(second);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                String script = URLEncoder.encode("Hello ${body}", "UTF-8");
+                endpoint = context.getEndpoint("language:simple:" + script + "?transform=false&cacheScript=false",
LanguageEndpoint.class);
+
+                from("direct:start")
+                    .to(endpoint)
+                    .to("mock:result");
+            }
+        };
+    }
+}


Mime
View raw message