[jboss-svn-commits] JBL Code SVN: r18596 - in labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/rosetta: tests/src/org/jboss/soa/esb/actions/scripting and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Feb 26 12:02:10 EST 2008


Author: tfennelly
Date: 2008-02-26 12:02:10 -0500 (Tue, 26 Feb 2008)
New Revision: 18596

Modified:
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/rosetta/src/org/jboss/soa/esb/actions/scripting/GroovyActionProcessor.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/actions/scripting/GroovyActionProcessorUnitTest.java
Log:
http://jira.jboss.com/jira/browse/JBESB-1560
http://jira.jboss.com/jira/browse/JBESB-1561
http://jira.jboss.com/jira/browse/JBESB-1565

Modified: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/rosetta/src/org/jboss/soa/esb/actions/scripting/GroovyActionProcessor.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/rosetta/src/org/jboss/soa/esb/actions/scripting/GroovyActionProcessor.java	2008-02-26 16:43:32 UTC (rev 18595)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/rosetta/src/org/jboss/soa/esb/actions/scripting/GroovyActionProcessor.java	2008-02-26 17:02:10 UTC (rev 18596)
@@ -21,25 +21,25 @@
 
 import groovy.lang.Binding;
 import groovy.lang.GroovyShell;
+import groovy.lang.Script;
 import groovy.util.GroovyScriptEngine;
-
-import java.io.IOException;
-import java.io.InputStream;
-
 import org.apache.log4j.Logger;
 import org.jboss.internal.soa.esb.util.StreamUtils;
 import org.jboss.soa.esb.ConfigurationException;
-import org.jboss.soa.esb.listeners.message.MessageDeliverException;
 import org.jboss.soa.esb.actions.ActionLifecycleException;
 import org.jboss.soa.esb.actions.ActionPipelineProcessor;
 import org.jboss.soa.esb.actions.ActionProcessingException;
 import org.jboss.soa.esb.actions.ActionUtils;
 import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.listeners.message.MessageDeliverException;
 import org.jboss.soa.esb.message.Message;
 import org.jboss.soa.esb.message.MessagePayloadProxy;
 import org.jboss.soa.esb.message.body.content.BytesBody;
 import org.jboss.soa.esb.util.ClassUtil;
 
+import java.io.IOException;
+import java.io.InputStream;
+
 /**
  * <a href="http://groovy.codehaus.org">Groovy</a> Scripting action processor.
  * <p/>
@@ -53,7 +53,10 @@
  * {@link ConfigTree configuration} is bound under the name "config".
  * <p/>
  * The script can also be supplied to this action as the message payload, allowing you to
- * dynamically supply the action with script.
+ * dynamically supply the action script.  For message based scripts to be executable,
+ * the "script" action property must be omitted and the "supportMessageBasedScripting" property must
+ * be set to "true".  There are obvious security issues around executing message based scripts,
+ * so use this feature controlled manner.
  *
  * @author Gregory Pierce.
  * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
@@ -63,7 +66,9 @@
     private static Logger logger = Logger.getLogger(GroovyActionProcessor.class);
     protected ConfigTree configTree;
     protected GroovyScriptEngine scriptEngine;
-    private String script;
+    private String scriptPath;
+    private Script script;
+    private boolean cacheScript;
     private MessagePayloadProxy payloadProxy;
 
     public GroovyActionProcessor(ConfigTree config) throws ConfigurationException {
@@ -74,16 +79,15 @@
     }
 
     public void initialise() throws ActionLifecycleException {
-        String scriptPath = configTree.getAttribute("script");
-
+        scriptPath = configTree.getAttribute("script");
+        cacheScript = configTree.getBooleanAttribute("cacheScript", true);
         if(scriptPath == null) {
-            logger.info("No Groovy script specified on action config " + configTree.getAttribute("name")
-                    + ". Expecting Groovy script to be in message.");
-        } else {
-            try {
-                script = GroovyActionProcessor.getScriptFromClasspath(scriptPath);
-            } catch (IOException e) {
-                throw new ActionLifecycleException("Error reading script '" + scriptPath + "' stream.");
+            boolean supportMessageBasedScripting = configTree.getBooleanAttribute("supportMessageBasedScripting", false);
+            if(supportMessageBasedScripting) {
+                logger.info("No Groovy script specified on action config " + configTree.getAttribute("name")
+                        + ". Expecting Groovy script to be in message.");
+            } else {
+                throw new ActionLifecycleException("'script' not configured on the action and message based scripting is not enabled ('supportMessageBasedScripting=false').");
             }
         }
     }
@@ -137,8 +141,12 @@
             binding.setVariable("config", configTree);
             binding.setVariable("payloadProxy", payloadProxy);
 
-            GroovyShell shell = new GroovyShell(Thread.currentThread().getContextClassLoader(), binding);
-            Object returnVal = shell.evaluate(getScript(message));
+            Script execScript = getScript(message);
+            Object returnVal;
+            synchronized (execScript) {
+                execScript.setBinding(binding);
+                returnVal = execScript.run();
+            }
 
             if(returnVal instanceof Message) {
                 return (Message) returnVal;
@@ -152,8 +160,17 @@
 		}
 	}
 
-    private String getScript(Message message) throws ActionProcessingException {
-        if(script != null) {
+    protected Script getScript(Message message) throws ActionProcessingException {
+        if(scriptPath != null) {
+            if(script == null || !cacheScript) {
+                try {
+                    String scriptText = GroovyActionProcessor.getScriptFromClasspath(scriptPath);
+                    script = constructScriptInstance(scriptText);
+                } catch (IOException e) {
+                    throw new ActionProcessingException("Error reading script '" + scriptPath + "' stream.");
+                }
+            }
+            
             return script;
         } else {
             // So, the script is being passed in in the message... 
@@ -166,15 +183,20 @@
             }
 
             if(messageScript instanceof String) {
-                return (String)messageScript;
+                return constructScriptInstance((String)messageScript);
             } else if(messageScript instanceof byte[]) {
-                return new String((byte[])messageScript);
+                return constructScriptInstance(new String((byte[])messageScript));
             } else {
                 throw new ActionProcessingException("Groovy script not specified in message.");
             }
         }
     }
 
+    private Script constructScriptInstance(String scriptText) {
+        GroovyShell shell = new GroovyShell(Thread.currentThread().getContextClassLoader());
+        return shell.parse(scriptText);
+    }
+
     public void processException(final Message message, final Throwable th) {
     }
 

Modified: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/actions/scripting/GroovyActionProcessorUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/actions/scripting/GroovyActionProcessorUnitTest.java	2008-02-26 16:43:32 UTC (rev 18595)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/actions/scripting/GroovyActionProcessorUnitTest.java	2008-02-26 17:02:10 UTC (rev 18596)
@@ -24,10 +24,8 @@
 import org.jboss.soa.esb.ConfigurationException;
 import org.jboss.soa.esb.actions.ActionLifecycleException;
 import org.jboss.soa.esb.actions.ActionProcessingException;
-import org.jboss.soa.esb.actions.ActionUtils;
 import org.jboss.soa.esb.helpers.ConfigTree;
 import org.jboss.soa.esb.message.Message;
-import org.jboss.soa.esb.message.body.content.BytesBody;
 import org.jboss.soa.esb.message.format.MessageFactory;
 
 /**
@@ -45,10 +43,35 @@
         GroovyActionProcessor processor = new GroovyActionProcessor(config);
         Message message = MessageFactory.getInstance().getMessage();
 
-        assertProcessingOK(processor, message, messageContents);
+        assertProcessingOK(processor, message, messageContents, null);
     }
 
-    public void test_script_inlined() throws ConfigurationException, ActionLifecycleException, ActionProcessingException {
+    public void test_script_caching_on() throws ConfigurationException, ActionLifecycleException, ActionProcessingException {
+        ConfigTree config = getConfig("test.groovy");
+        GroovyActionProcessor processor = new GroovyActionProcessor(config);
+        Message message = MessageFactory.getInstance().getMessage();
+
+        processor.initialise();
+        // Test script caching...
+        assertTrue("script should not be null", processor.getScript(message) != null);
+        assertTrue("script should be cached", processor.getScript(message) == processor.getScript(message));                
+    }
+
+    public void test_script_caching_off() throws ConfigurationException, ActionLifecycleException, ActionProcessingException {
+        ConfigTree config = getConfig("test.groovy");
+        GroovyActionProcessor processor;
+        Message message = MessageFactory.getInstance().getMessage();
+
+        config.setAttribute("cacheScript", "false");
+        processor = new GroovyActionProcessor(config);
+
+        processor.initialise();
+        // Test script caching...
+        assertTrue("script should not be null", processor.getScript(message) != null);
+        assertTrue("script should not be cached", processor.getScript(message) != processor.getScript(message));
+    }
+
+    public void test_script_inlined_fail() throws ConfigurationException, ActionLifecycleException, ActionProcessingException {
         ConfigTree config = new ConfigTree("<config/>");
         String messageContents = "Hello World - Inlined!";
 
@@ -61,17 +84,41 @@
         message.getBody().add("import org.jboss.soa.esb.message.*\n" +
                 "message.getBody().add(config.getAttribute(\"messageContents\").getBytes());");
 
-        assertProcessingOK(processor, message, messageContents);
+        assertProcessingOK(processor, message, messageContents, "'script' not configured on the action and message based scripting is not enabled ('supportMessageBasedScripting=false').");
     }
 
-    private void assertProcessingOK(GroovyActionProcessor processor, Message message, String messageContents) throws ActionLifecycleException, ActionProcessingException {
-        processor.initialise();
-        processor.process(message);
-        byte[] bodyContents = (byte[]) message.getBody().get();
-        assertNotNull("Expected body contents to be set.", bodyContents);
-        assertEquals(messageContents, new String(bodyContents));
+    public void test_script_inlined_success() throws ConfigurationException, ActionLifecycleException, ActionProcessingException {
+        ConfigTree config = new ConfigTree("<config/>");
+        String messageContents = "Hello World - Inlined!";
+
+        config.setAttribute("messageContents", messageContents);
+        config.setAttribute("supportMessageBasedScripting", "true");
+
+        GroovyActionProcessor processor = new GroovyActionProcessor(config);
+        Message message = MessageFactory.getInstance().getMessage();
+
+        // Set the script as the message task object...
+        message.getBody().add("import org.jboss.soa.esb.message.*\n" +
+                "message.getBody().add(config.getAttribute(\"messageContents\").getBytes());");
+
+        assertProcessingOK(processor, message, messageContents, null);
     }
 
+    private void assertProcessingOK(GroovyActionProcessor processor, Message message, String messageContents, String errorMessage) throws ActionLifecycleException, ActionProcessingException {
+        try {
+            processor.initialise();
+            processor.process(message);
+            byte[] bodyContents = (byte[]) message.getBody().get();
+            assertNotNull("Expected body contents to be set.", bodyContents);
+            assertEquals(messageContents, new String(bodyContents));
+            if(errorMessage != null) {
+                fail("Expected error message: \"" + errorMessage + "\".");
+            }
+        } catch(ActionLifecycleException e) {
+            assertEquals(errorMessage, e.getMessage());
+        }
+    }
+
     private ConfigTree getConfig(String script) {
         ConfigTree config = new ConfigTree("<config/>");
 




More information about the jboss-svn-commits mailing list