From 8e198730f1e06c6d8c8476ec80b47d3327adc170 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 11 May 2014 10:31:09 +0200 Subject: o Supporting extraction of build parameters from the message. --- .../plugins/activemq/ActiveMqBuildTrigger.java | 59 ++++++++++++++++++---- .../jenkinsci/plugins/activemq/ActiveMqPlugin.java | 33 ++++++++---- .../plugins/activemq/DoBuildResponse.java | 34 +++++++++++++ 3 files changed, 107 insertions(+), 19 deletions(-) create mode 100644 src/main/java/org/jenkinsci/plugins/activemq/DoBuildResponse.java diff --git a/src/main/java/org/jenkinsci/plugins/activemq/ActiveMqBuildTrigger.java b/src/main/java/org/jenkinsci/plugins/activemq/ActiveMqBuildTrigger.java index 08a6faf..ad9d06f 100644 --- a/src/main/java/org/jenkinsci/plugins/activemq/ActiveMqBuildTrigger.java +++ b/src/main/java/org/jenkinsci/plugins/activemq/ActiveMqBuildTrigger.java @@ -2,8 +2,11 @@ package org.jenkinsci.plugins.activemq; import hudson.Extension; import hudson.model.AbstractProject; +import hudson.model.BooleanParameterValue; import hudson.model.BuildableItem; import hudson.model.Item; +import hudson.model.ParameterValue; +import hudson.model.StringParameterValue; import hudson.triggers.Trigger; import hudson.triggers.TriggerDescriptor; import hudson.util.FormValidation; @@ -15,11 +18,14 @@ import org.slf4j.Logger; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptException; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.TreeMap; import static java.lang.Boolean.TRUE; import static java.util.Collections.singletonMap; +import static org.apache.commons.lang.StringUtils.trimToEmpty; import static org.apache.commons.lang.StringUtils.trimToNull; import static org.jenkinsci.plugins.activemq.ActiveMqClient.BuildRequest; import static org.slf4j.LoggerFactory.getLogger; @@ -28,6 +34,8 @@ public class ActiveMqBuildTrigger extends Trigger { private static final Logger log = getLogger(ActiveMqBuildTrigger.class); + public static final String FUNCTION_NAME = "match"; + private String expression; private transient ActiveMqPlugin plugin; @@ -72,7 +80,7 @@ public class ActiveMqBuildTrigger extends Trigger { engine.eval(expression); - if (checkEngine(engine)) { + if (!checkEngine(engine)) { log.warn("Invalid expression: {}", expression); } } catch (Exception e) { @@ -80,24 +88,55 @@ public class ActiveMqBuildTrigger extends Trigger { } } - public boolean matches(BuildRequest req) { + public DoBuildResponse matches(BuildRequest req) { if (engine == null) { - return false; + return new DoBuildResponse.NoBuild(); } Map parameters = new TreeMap(req.parameters); Map> context = singletonMap("parameters", parameters); try { - Object o = ((Invocable) engine).invokeFunction("match", parameters); + Object o = ((Invocable) engine).invokeFunction(FUNCTION_NAME, parameters); log.info("o = " + o); + if (o != null) { + log.info("o.getClass() = " + o.getClass()); + } - Boolean b = null; if (o instanceof Boolean) { - b = (Boolean) o; + Boolean b = (Boolean) o; + if (b) { + return new DoBuildResponse.Build(); + } + } else if (o instanceof Map) { + Map map = (Map) o; + List buildParameters = new ArrayList(); + for (Map.Entry e : map.entrySet()) { + Object key = e.getKey(); + if (key == null || !(key instanceof String)) { + continue; + } + + String k = trimToNull(key.toString()); + if (k == null) { + continue; + } + + Object value = e.getValue(); + if (value instanceof Boolean) { + Boolean b = (Boolean) value; + buildParameters.add(new BooleanParameterValue(k, b)); + } else if (value instanceof String) { + String v = trimToEmpty(value.toString()); + + buildParameters.add(new StringParameterValue(k, v)); + } + } + + return new DoBuildResponse.BuildWithParameters(buildParameters); } - return b != null && b; + return new DoBuildResponse.NoBuild(); } catch (Exception e) { log.warn("Could not evaluate expression:"); log.warn(expression); @@ -106,7 +145,7 @@ public class ActiveMqBuildTrigger extends Trigger { log.warn("{} = {}", entry.getKey(), entry.getValue()); } log.warn("Exception", e); - return false; + return new DoBuildResponse.NoBuild(); } } @@ -140,7 +179,7 @@ public class ActiveMqBuildTrigger extends Trigger { return FormValidation.ok(); } - return FormValidation.warning("The expression must define a function named 'match'"); + return FormValidation.warning("The expression must define a function named '" + FUNCTION_NAME + "'"); } catch (ScriptException e) { return FormValidation.error("Could not evaluate expression: " + e.getMessage()); } catch (Exception e) { @@ -150,7 +189,7 @@ public class ActiveMqBuildTrigger extends Trigger { } private static boolean checkEngine(ScriptEngine engine) throws ScriptException { - Object o = engine.eval("typeof match === 'function'"); + Object o = engine.eval("typeof " + FUNCTION_NAME + " === 'function'"); return TRUE.equals(o); } diff --git a/src/main/java/org/jenkinsci/plugins/activemq/ActiveMqPlugin.java b/src/main/java/org/jenkinsci/plugins/activemq/ActiveMqPlugin.java index cf1c2e9..d1a9d8d 100644 --- a/src/main/java/org/jenkinsci/plugins/activemq/ActiveMqPlugin.java +++ b/src/main/java/org/jenkinsci/plugins/activemq/ActiveMqPlugin.java @@ -5,15 +5,17 @@ import hudson.Plugin; import hudson.model.AbstractProject; import hudson.model.Build; import hudson.model.Cause; +import hudson.model.CauseAction; +import hudson.model.ParametersAction; import hudson.model.TaskListener; import jenkins.model.GlobalConfiguration; import jenkins.model.Jenkins; +import jenkins.util.TimeDuration; import org.slf4j.Logger; import javax.annotation.Nonnull; import javax.jms.JMSException; import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineManager; import java.net.URISyntaxException; import java.util.Map; @@ -107,11 +109,24 @@ public class ActiveMqPlugin extends Plugin implements ActiveMqClient.BuildReques continue; } - if (trigger.matches(req)) { - log.debug("MVEL matched!"); - project.scheduleBuild(new ActiveMqCause()); + DoBuildResponse doBuildResponse = trigger.matches(req); + if (doBuildResponse instanceof DoBuildResponse.NoBuild) { + log.debug("Trigger did not match"); } else { - log.debug("MVEL did not match"); + log.debug("Trigger matched: {}", doBuildResponse.getClass().getSimpleName()); + + if (doBuildResponse instanceof DoBuildResponse.BuildWithParameters && project.isParameterized()) { + DoBuildResponse.BuildWithParameters buildWithParameters = (DoBuildResponse.BuildWithParameters) doBuildResponse; + + TimeDuration delay = new TimeDuration(project.getQuietPeriod()); + + ParametersAction parametersAction = new ParametersAction(buildWithParameters.parameters); + CauseAction causeAction = new CauseAction(new ActiveMqCause()); + + Jenkins.getInstance().getQueue().schedule(project, delay.getTime(), parametersAction, causeAction); + } else { + project.scheduleBuild(new ActiveMqCause()); + } } } } @@ -127,10 +142,10 @@ public class ActiveMqPlugin extends Plugin implements ActiveMqClient.BuildReques * Used by other parts of the plugin. */ public ScriptEngine createEngine() { - log.info("ActiveMqPlugin.createEngine"); - for (ScriptEngineFactory scriptEngineFactory : scriptEngineManager.getEngineFactories()) { - log.info("scriptEngineFactory = " + scriptEngineFactory); + ScriptEngine engine = scriptEngineManager.getEngineByName("JavaScript"); + if (engine == null) { + throw new RuntimeException("Unable to create script engine"); } - return scriptEngineManager.getEngineByName("JavaScript"); + return engine; } } diff --git a/src/main/java/org/jenkinsci/plugins/activemq/DoBuildResponse.java b/src/main/java/org/jenkinsci/plugins/activemq/DoBuildResponse.java new file mode 100644 index 0000000..151e4bc --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/activemq/DoBuildResponse.java @@ -0,0 +1,34 @@ +package org.jenkinsci.plugins.activemq; + +import hudson.model.ParameterValue; + +import java.util.List; + +public abstract class DoBuildResponse { + public final boolean shouldBuild; + + protected DoBuildResponse(boolean shouldBuild) { + this.shouldBuild = shouldBuild; + } + + public static class NoBuild extends DoBuildResponse { + public NoBuild() { + super(false); + } + } + + public static class BuildWithParameters extends DoBuildResponse { + public final List parameters; + + public BuildWithParameters(List parameters) { + super(true); + this.parameters = parameters; + } + } + + public static class Build extends DoBuildResponse { + public Build() { + super(true); + } + } +} -- cgit v1.2.3