From e9bda13f532b86fab4ece6b09833fc45ee039fe3 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Tue, 25 Sep 2018 11:28:50 -0700 Subject: [PATCH 01/12] Scripting: Add watcher script contexts This commit removes the use of ExecutableScript from watcher in favor of custom script contexts for both watcher condition scripts and transform scripts. --- .../elasticsearch/script/ParameterMap.java | 7 +- .../elasticsearch/xpack/watcher/Watcher.java | 9 +-- .../actions/email/ExecutableEmailAction.java | 2 +- .../hipchat/ExecutableHipChatAction.java | 2 +- .../actions/jira/ExecutableJiraAction.java | 2 +- .../logging/ExecutableLoggingAction.java | 2 +- .../pagerduty/ExecutablePagerDutyAction.java | 2 +- .../actions/slack/ExecutableSlackAction.java | 2 +- .../webhook/ExecutableWebhookAction.java | 2 +- .../condition/AbstractCompareCondition.java | 2 +- .../watcher/condition/ScriptCondition.java | 19 ++--- .../condition/WatcherConditionScript.java | 75 ++++++++++++++++++ .../input/http/ExecutableHttpInput.java | 2 +- .../attachment/DataAttachmentParser.java | 2 +- .../HttpEmailAttachementParser.java | 2 +- .../attachment/ReportingAttachmentParser.java | 2 +- .../xpack/watcher/support/Variables.java | 14 ++-- .../search/WatcherSearchTemplateService.java | 2 +- .../script/ExecutableScriptTransform.java | 16 +--- .../script/WatcherTransformScript.java | 76 +++++++++++++++++++ .../condition/ScriptConditionTests.java | 4 +- .../input/transform/TransformInputTests.java | 3 +- .../xpack/watcher/support/VariablesTests.java | 2 +- .../test/integration/SearchInputTests.java | 3 +- .../script/ScriptTransformTests.java | 41 +++++----- 25 files changed, 216 insertions(+), 79 deletions(-) create mode 100644 x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java create mode 100644 x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/WatcherTransformScript.java diff --git a/server/src/main/java/org/elasticsearch/script/ParameterMap.java b/server/src/main/java/org/elasticsearch/script/ParameterMap.java index b4fd24b059bd8..b59d057d66e62 100644 --- a/server/src/main/java/org/elasticsearch/script/ParameterMap.java +++ b/server/src/main/java/org/elasticsearch/script/ParameterMap.java @@ -19,11 +19,12 @@ package org.elasticsearch.script; +import org.apache.logging.log4j.LogManager; +import org.elasticsearch.common.logging.DeprecationLogger; + import java.util.Collection; import java.util.Map; import java.util.Set; -import org.apache.logging.log4j.LogManager; -import org.elasticsearch.common.logging.DeprecationLogger; public final class ParameterMap implements Map { @@ -34,7 +35,7 @@ public final class ParameterMap implements Map { private final Map deprecations; - ParameterMap(Map params, Map deprecations) { + public ParameterMap(Map params, Map deprecations) { this.params = params; this.deprecations = deprecations; } diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java index 32d492b78a7a7..51b44e4c0255a 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java @@ -48,7 +48,6 @@ import org.elasticsearch.plugins.ScriptPlugin; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestHandler; -import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptService; import org.elasticsearch.script.SearchScript; @@ -106,6 +105,7 @@ import org.elasticsearch.xpack.watcher.condition.InternalAlwaysCondition; import org.elasticsearch.xpack.watcher.condition.NeverCondition; import org.elasticsearch.xpack.watcher.condition.ScriptCondition; +import org.elasticsearch.xpack.watcher.condition.WatcherConditionScript; import org.elasticsearch.xpack.watcher.execution.AsyncTriggerEventConsumer; import org.elasticsearch.xpack.watcher.execution.ExecutionService; import org.elasticsearch.xpack.watcher.execution.InternalWatchExecutor; @@ -152,6 +152,7 @@ import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateService; import org.elasticsearch.xpack.watcher.transform.script.ScriptTransform; import org.elasticsearch.xpack.watcher.transform.script.ScriptTransformFactory; +import org.elasticsearch.xpack.watcher.transform.script.WatcherTransformScript; import org.elasticsearch.xpack.watcher.transform.search.SearchTransform; import org.elasticsearch.xpack.watcher.transform.search.SearchTransformFactory; import org.elasticsearch.xpack.watcher.transport.actions.ack.TransportAckWatchAction; @@ -225,9 +226,6 @@ public class Watcher extends Plugin implements ActionPlugin, ScriptPlugin, Reloa public static final ScriptContext SCRIPT_SEARCH_CONTEXT = new ScriptContext<>("xpack", SearchScript.Factory.class); - // TODO: remove this context when each xpack script use case has their own contexts - public static final ScriptContext SCRIPT_EXECUTABLE_CONTEXT - = new ScriptContext<>("xpack_executable", ExecutableScript.Factory.class); public static final ScriptContext SCRIPT_TEMPLATE_CONTEXT = new ScriptContext<>("xpack_template", TemplateScript.Factory.class); @@ -673,7 +671,8 @@ public List getBootstrapChecks() { @Override public List> getContexts() { - return Arrays.asList(Watcher.SCRIPT_SEARCH_CONTEXT, Watcher.SCRIPT_EXECUTABLE_CONTEXT, Watcher.SCRIPT_TEMPLATE_CONTEXT); + return Arrays.asList(Watcher.SCRIPT_SEARCH_CONTEXT, WatcherTransformScript.CONTEXT, + WatcherConditionScript.CONTEXT, Watcher.SCRIPT_TEMPLATE_CONTEXT); } @Override diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/email/ExecutableEmailAction.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/email/ExecutableEmailAction.java index f737d89c1286d..fcc4eb0e9422b 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/email/ExecutableEmailAction.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/email/ExecutableEmailAction.java @@ -41,7 +41,7 @@ public ExecutableEmailAction(EmailAction action, Logger logger, EmailService ema } public Action.Result execute(String actionId, WatchExecutionContext ctx, Payload payload) throws Exception { - Map model = Variables.createCtxModel(ctx, payload); + Map model = Variables.createCtxParamsMap(ctx, payload); Map attachments = new HashMap<>(); DataAttachment dataAttachment = action.getDataAttachment(); diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/hipchat/ExecutableHipChatAction.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/hipchat/ExecutableHipChatAction.java index 5772d1ffa6f1f..176de8b945df2 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/hipchat/ExecutableHipChatAction.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/hipchat/ExecutableHipChatAction.java @@ -39,7 +39,7 @@ public Action.Result execute(final String actionId, WatchExecutionContext ctx, P // watch/action were created. account.validateParsedTemplate(ctx.id().watchId(), actionId, action.message); - Map model = Variables.createCtxModel(ctx, payload); + Map model = Variables.createCtxParamsMap(ctx, payload); HipChatMessage message = account.render(ctx.id().watchId(), actionId, templateEngine, action.message, model); if (ctx.simulateAction(actionId)) { diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/jira/ExecutableJiraAction.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/jira/ExecutableJiraAction.java index acb0c8ce59142..89f9af8e1d529 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/jira/ExecutableJiraAction.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/jira/ExecutableJiraAction.java @@ -42,7 +42,7 @@ public Action.Result execute(final String actionId, WatchExecutionContext ctx, P throw new IllegalStateException("account [" + action.account + "] was not found. perhaps it was deleted"); } - final Function render = s -> engine.render(new TextTemplate(s), Variables.createCtxModel(ctx, payload)); + final Function render = s -> engine.render(new TextTemplate(s), Variables.createCtxParamsMap(ctx, payload)); Map fields = new HashMap<>(); // Apply action fields diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/logging/ExecutableLoggingAction.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/logging/ExecutableLoggingAction.java index b1cb723949d8e..83fdb4e7c1fef 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/logging/ExecutableLoggingAction.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/logging/ExecutableLoggingAction.java @@ -40,7 +40,7 @@ Logger textLogger() { @Override public Action.Result execute(String actionId, WatchExecutionContext ctx, Payload payload) throws Exception { - Map model = Variables.createCtxModel(ctx, payload); + Map model = Variables.createCtxParamsMap(ctx, payload); String loggedText = templateEngine.render(action.text, model); if (ctx.simulateAction(actionId)) { diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/pagerduty/ExecutablePagerDutyAction.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/pagerduty/ExecutablePagerDutyAction.java index 59381dc33362c..0c995ce94ef10 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/pagerduty/ExecutablePagerDutyAction.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/pagerduty/ExecutablePagerDutyAction.java @@ -40,7 +40,7 @@ public Action.Result execute(final String actionId, WatchExecutionContext ctx, P throw new IllegalStateException("account [" + action.event.account + "] was not found. perhaps it was deleted"); } - Map model = Variables.createCtxModel(ctx, payload); + Map model = Variables.createCtxParamsMap(ctx, payload); IncidentEvent event = action.event.render(ctx.watch().id(), actionId, templateEngine, model, account.getDefaults()); if (ctx.simulateAction(actionId)) { diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/slack/ExecutableSlackAction.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/slack/ExecutableSlackAction.java index 9ab4a028ca13d..b904b05ada703 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/slack/ExecutableSlackAction.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/slack/ExecutableSlackAction.java @@ -40,7 +40,7 @@ public Action.Result execute(final String actionId, WatchExecutionContext ctx, P throw new IllegalStateException("account [" + action.account + "] was not found. perhaps it was deleted"); } - Map model = Variables.createCtxModel(ctx, payload); + Map model = Variables.createCtxParamsMap(ctx, payload); SlackMessage message = action.message.render(ctx.id().watchId(), actionId, templateEngine, model, account.getMessageDefaults()); if (ctx.simulateAction(actionId)) { diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/webhook/ExecutableWebhookAction.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/webhook/ExecutableWebhookAction.java index 7313d529b4aea..ec1f5774b13f3 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/webhook/ExecutableWebhookAction.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/actions/webhook/ExecutableWebhookAction.java @@ -31,7 +31,7 @@ public ExecutableWebhookAction(WebhookAction action, Logger logger, HttpClient h @Override public Action.Result execute(String actionId, WatchExecutionContext ctx, Payload payload) throws Exception { - Map model = Variables.createCtxModel(ctx, payload); + Map model = Variables.createCtxParamsMap(ctx, payload); HttpRequest request = action.requestTemplate.render(templateEngine, model); diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/AbstractCompareCondition.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/AbstractCompareCondition.java index 555f9d465458a..81e3eb464e69b 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/AbstractCompareCondition.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/AbstractCompareCondition.java @@ -36,7 +36,7 @@ protected AbstractCompareCondition(String type, Clock clock) { @Override public final Result execute(WatchExecutionContext ctx) { Map resolvedValues = new HashMap<>(); - Map model = Variables.createCtxModel(ctx, ctx.payload()); + Map model = Variables.createCtxParamsMap(ctx, ctx.payload()); return doExecute(model, resolvedValues); } diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/ScriptCondition.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/ScriptCondition.java index e2befe9a24e68..57e3351f0c05b 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/ScriptCondition.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/ScriptCondition.java @@ -8,19 +8,15 @@ import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptService; import org.elasticsearch.xpack.core.watcher.condition.ExecutableCondition; import org.elasticsearch.xpack.core.watcher.execution.WatchExecutionContext; -import org.elasticsearch.xpack.watcher.Watcher; import org.elasticsearch.xpack.watcher.support.Variables; import java.io.IOException; import java.util.Map; -import static org.elasticsearch.xpack.core.watcher.support.Exceptions.illegalState; - /** * This class executes a script against the ctx payload and returns a boolean */ @@ -31,7 +27,7 @@ public final class ScriptCondition implements ExecutableCondition { private final ScriptService scriptService; private final Script script; - private final ExecutableScript.Factory scriptFactory; + private final WatcherConditionScript.Factory scriptFactory; public ScriptCondition(Script script) { this.script = script; @@ -42,7 +38,7 @@ public ScriptCondition(Script script) { ScriptCondition(Script script, ScriptService scriptService) { this.scriptService = scriptService; this.script = script; - scriptFactory = scriptService.compile(script, Watcher.SCRIPT_EXECUTABLE_CONTEXT); + scriptFactory = scriptService.compile(script, WatcherConditionScript.CONTEXT); } public Script getScript() { @@ -65,17 +61,12 @@ public Result execute(WatchExecutionContext ctx) { } public Result doExecute(WatchExecutionContext ctx) { - Map parameters = Variables.createCtxModel(ctx, ctx.payload()); + Map parameters = Variables.createCtxParamsMap(ctx, ctx.payload()); if (script.getParams() != null && !script.getParams().isEmpty()) { parameters.putAll(script.getParams()); } - ExecutableScript executable = scriptFactory.newInstance(parameters); - Object value = executable.run(); - if (value instanceof Boolean) { - return (Boolean) value ? MET : UNMET; - } - throw illegalState("condition [{}] must return a boolean value (true|false) but instead returned [{}]", type(), ctx.watch().id(), - script, value); + WatcherConditionScript conditionScript = scriptFactory.newInstance(script.getParams(), ctx); + return conditionScript.execute() ? MET : UNMET; } @Override diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java new file mode 100644 index 0000000000000..a2a2b9c722681 --- /dev/null +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java @@ -0,0 +1,75 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch 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.elasticsearch.xpack.watcher.condition; + +import org.elasticsearch.script.ParameterMap; +import org.elasticsearch.script.ScriptContext; +import org.elasticsearch.xpack.core.watcher.execution.WatchExecutionContext; +import org.elasticsearch.xpack.watcher.support.Variables; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * A script to determine whether a watch should be run. + */ +public abstract class WatcherConditionScript { + + private static final Map DEPRECATIONS; + + static { + Map deprecations = new HashMap<>(); + deprecations.put( + "ctx", + "Accessing variable [ctx] via [params.ctx] from within a watcher_condition script " + + "is deprecated in favor of directly accessing [ctx]." + ); + DEPRECATIONS = Collections.unmodifiableMap(deprecations); + } + + private final Map params; + // TODO: ctx should have its members extracted into execute parameters, but it needs to be a member bwc access in params + private final Map ctx; + + public WatcherConditionScript(Map params, WatchExecutionContext watcherContext) { + Map paramsWithCtx = new HashMap<>(params); + Map ctx = Variables.createCtx(watcherContext, watcherContext.payload()); + paramsWithCtx.put("ctx", ctx); + this.params = new ParameterMap(Collections.unmodifiableMap(paramsWithCtx), DEPRECATIONS); + this.ctx = ctx; + } + + public abstract boolean execute(); + + public Map getParams() { + return params; + } + + public Map getCtx() { + return ctx; + } + + public interface Factory { + WatcherConditionScript newInstance(Map params, WatchExecutionContext watcherContext); + } + + public static ScriptContext CONTEXT = new ScriptContext<>("watcher_condition", Factory.class); +} diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/input/http/ExecutableHttpInput.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/input/http/ExecutableHttpInput.java index 1bc7ab309f0aa..5d738772f21cb 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/input/http/ExecutableHttpInput.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/input/http/ExecutableHttpInput.java @@ -44,7 +44,7 @@ public ExecutableHttpInput(HttpInput input, Logger logger, HttpClient client, Te public HttpInput.Result execute(WatchExecutionContext ctx, Payload payload) { HttpRequest request = null; try { - Map model = Variables.createCtxModel(ctx, payload); + Map model = Variables.createCtxParamsMap(ctx, payload); request = input.getRequest().render(templateEngine, model); return doExecute(ctx, request); } catch (Exception e) { diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/DataAttachmentParser.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/DataAttachmentParser.java index 9164e1db7ea1b..34730c88ce01b 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/DataAttachmentParser.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/DataAttachmentParser.java @@ -57,7 +57,7 @@ public DataAttachment parse(String id, XContentParser parser) throws IOException @Override public Attachment toAttachment(WatchExecutionContext ctx, Payload payload, DataAttachment attachment) throws IOException { - Map model = Variables.createCtxModel(ctx, payload); + Map model = Variables.createCtxParamsMap(ctx, payload); return attachment.getDataAttachment().create(attachment.id(), model); } } diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/HttpEmailAttachementParser.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/HttpEmailAttachementParser.java index 7c5d68a126b2c..076c57c832fb4 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/HttpEmailAttachementParser.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/HttpEmailAttachementParser.java @@ -79,7 +79,7 @@ public HttpRequestAttachment parse(String id, XContentParser parser) throws IOEx @Override public Attachment toAttachment(WatchExecutionContext context, Payload payload, HttpRequestAttachment attachment) throws IOException { - Map model = Variables.createCtxModel(context, payload); + Map model = Variables.createCtxParamsMap(context, payload); HttpRequest httpRequest = attachment.getRequestTemplate().render(templateEngine, model); HttpResponse response = httpClient.execute(httpRequest); diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/ReportingAttachmentParser.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/ReportingAttachmentParser.java index 28a8c194b579f..f6026c0efce3b 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/ReportingAttachmentParser.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/ReportingAttachmentParser.java @@ -91,7 +91,7 @@ public ReportingAttachment parse(String id, XContentParser parser) throws IOExce @Override public Attachment toAttachment(WatchExecutionContext context, Payload payload, ReportingAttachment attachment) throws IOException { - Map model = Variables.createCtxModel(context, payload); + Map model = Variables.createCtxParamsMap(context, payload); String initialUrl = templateEngine.render(new TextTemplate(attachment.url()), model); diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/Variables.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/Variables.java index 858f6707f29a9..fc82e51352ddf 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/Variables.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/Variables.java @@ -22,7 +22,13 @@ public final class Variables { public static final String METADATA = "metadata"; public static final String VARS = "vars"; - public static Map createCtxModel(WatchExecutionContext ctx, Payload payload) { + public static Map createCtxParamsMap(WatchExecutionContext ctx, Payload payload) { + Map model = new HashMap<>(); + model.put(CTX, createCtx(ctx, payload)); + return model; + } + + public static Map createCtx(WatchExecutionContext ctx, Payload payload) { Map ctxModel = new HashMap<>(); ctxModel.put(ID, ctx.id().value()); ctxModel.put(WATCH_ID, ctx.id().watchId()); @@ -33,10 +39,6 @@ public static Map createCtxModel(WatchExecutionContext ctx, Payl } ctxModel.put(METADATA, ctx.watch().metadata()); ctxModel.put(VARS, ctx.vars()); - Map model = new HashMap<>(); - model.put(CTX, ctxModel); - return model; + return ctxModel; } - - } diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/search/WatcherSearchTemplateService.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/search/WatcherSearchTemplateService.java index 9df4f5f8b5234..2208aab428a39 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/search/WatcherSearchTemplateService.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/search/WatcherSearchTemplateService.java @@ -45,7 +45,7 @@ public WatcherSearchTemplateService(Settings settings, ScriptService scriptServi public String renderTemplate(Script source, WatchExecutionContext ctx, Payload payload) throws IOException { // Due the inconsistency with templates in ES 1.x, we maintain our own template format. // This template format we use now, will become the template structure in ES 2.0 - Map watcherContextParams = Variables.createCtxModel(ctx, payload); + Map watcherContextParams = Variables.createCtxParamsMap(ctx, payload); // Here we convert watcher template into a ES core templates. Due to the different format we use, we // convert to the template format used in ES core if (source.getParams() != null) { diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/ExecutableScriptTransform.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/ExecutableScriptTransform.java index e2b1cf882cc47..20cd8e7b6efd7 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/ExecutableScriptTransform.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/ExecutableScriptTransform.java @@ -8,19 +8,16 @@ import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.message.ParameterizedMessage; import org.apache.logging.log4j.util.Supplier; -import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptService; import org.elasticsearch.xpack.core.watcher.execution.WatchExecutionContext; import org.elasticsearch.xpack.core.watcher.transform.ExecutableTransform; import org.elasticsearch.xpack.core.watcher.watch.Payload; -import org.elasticsearch.xpack.watcher.Watcher; import java.io.IOException; import java.util.HashMap; import java.util.Map; -import static org.elasticsearch.xpack.watcher.support.Variables.createCtxModel; import static org.elasticsearch.xpack.watcher.transform.script.ScriptTransform.TYPE; public class ExecutableScriptTransform extends ExecutableTransform { @@ -32,7 +29,7 @@ public ExecutableScriptTransform(ScriptTransform transform, Logger logger, Scrip this.scriptService = scriptService; Script script = transform.getScript(); // try to compile so we catch syntax errors early - scriptService.compile(script, Watcher.SCRIPT_EXECUTABLE_CONTEXT); + scriptService.compile(script, WatcherTransformScript.CONTEXT); } @Override @@ -47,14 +44,9 @@ public ScriptTransform.Result execute(WatchExecutionContext ctx, Payload payload ScriptTransform.Result doExecute(WatchExecutionContext ctx, Payload payload) throws IOException { Script script = transform.getScript(); - Map model = new HashMap<>(); - if (script.getParams() != null) { - model.putAll(script.getParams()); - } - model.putAll(createCtxModel(ctx, payload)); - ExecutableScript.Factory factory = scriptService.compile(script, Watcher.SCRIPT_EXECUTABLE_CONTEXT); - ExecutableScript executable = factory.newInstance(model); - Object value = executable.run(); + WatcherTransformScript.Factory factory = scriptService.compile(script, WatcherTransformScript.CONTEXT); + WatcherTransformScript transformScript = factory.newInstance(script.getParams(), ctx, payload); + Object value = transformScript.execute(); // TODO: deprecate one of these styles (returning a map or returning an opaque value below) if (value instanceof Map) { return new ScriptTransform.Result(new Payload.Simple((Map) value)); diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/WatcherTransformScript.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/WatcherTransformScript.java new file mode 100644 index 0000000000000..adeeb5be67425 --- /dev/null +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/WatcherTransformScript.java @@ -0,0 +1,76 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch 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.elasticsearch.xpack.watcher.transform.script; + +import org.elasticsearch.script.ParameterMap; +import org.elasticsearch.script.ScriptContext; +import org.elasticsearch.xpack.core.watcher.execution.WatchExecutionContext; +import org.elasticsearch.xpack.core.watcher.watch.Payload; +import org.elasticsearch.xpack.watcher.support.Variables; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * A script to transform the results of a watch execution. + */ +public abstract class WatcherTransformScript { + + private static final Map DEPRECATIONS; + + static { + Map deprecations = new HashMap<>(); + deprecations.put( + "ctx", + "Accessing variable [ctx] via [params.ctx] from within a watcher_transform script " + + "is deprecated in favor of directly accessing [ctx]." + ); + DEPRECATIONS = Collections.unmodifiableMap(deprecations); + } + + private final Map params; + // TODO: ctx should have its members extracted into execute parameters, but it needs to be a member bwc access in params + private final Map ctx; + + public WatcherTransformScript(Map params, WatchExecutionContext watcherContext, Payload payload) { + Map paramsWithCtx = new HashMap<>(params); + Map ctx = Variables.createCtx(watcherContext, payload); + paramsWithCtx.put("ctx", ctx); + this.params = new ParameterMap(Collections.unmodifiableMap(paramsWithCtx), DEPRECATIONS); + this.ctx = ctx; + } + + public abstract Object execute(); + + public Map getParams() { + return params; + } + + public Map getCtx() { + return ctx; + } + + public interface Factory { + WatcherTransformScript newInstance(Map params, WatchExecutionContext watcherContext, Payload payload); + } + + public static ScriptContext CONTEXT = new ScriptContext<>("watcher_transform", Factory.class); +} diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java index c7b7f2c63cdde..71e547a08d4e4 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java @@ -31,8 +31,8 @@ import org.elasticsearch.xpack.core.watcher.condition.ExecutableCondition; import org.elasticsearch.xpack.core.watcher.execution.WatchExecutionContext; import org.elasticsearch.xpack.core.watcher.watch.Payload; -import org.elasticsearch.xpack.watcher.Watcher; import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase; +import org.elasticsearch.xpack.watcher.transform.script.WatcherTransformScript; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.junit.Before; @@ -85,7 +85,7 @@ public void init() throws IOException { ScriptEngine engine = new MockScriptEngine(MockScriptEngine.NAME, scripts); scriptService = new ScriptService(Settings.EMPTY, Collections.singletonMap(engine.getType(), engine), - Collections.singletonMap(Watcher.SCRIPT_EXECUTABLE_CONTEXT.name, Watcher.SCRIPT_EXECUTABLE_CONTEXT)); + Collections.singletonMap(WatcherTransformScript.CONTEXT.name, WatcherTransformScript.CONTEXT)); ClusterState.Builder clusterState = new ClusterState.Builder(new ClusterName("_name")); clusterState.metaData(MetaData.builder().putCustom(ScriptMetaData.TYPE, new ScriptMetaData.Builder(null).build())); diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/input/transform/TransformInputTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/input/transform/TransformInputTests.java index aee5a5e07f09e..9ebde46148dbe 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/input/transform/TransformInputTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/input/transform/TransformInputTests.java @@ -30,6 +30,7 @@ import org.elasticsearch.xpack.watcher.transform.script.ExecutableScriptTransform; import org.elasticsearch.xpack.watcher.transform.script.ScriptTransform; import org.elasticsearch.xpack.watcher.transform.script.ScriptTransformFactory; +import org.elasticsearch.xpack.watcher.transform.script.WatcherTransformScript; import org.junit.Before; import java.util.Collections; @@ -51,7 +52,7 @@ public void setupScriptService() { Map> contexts = new HashMap<>(); contexts.put(Watcher.SCRIPT_TEMPLATE_CONTEXT.name, Watcher.SCRIPT_TEMPLATE_CONTEXT); contexts.put(Watcher.SCRIPT_SEARCH_CONTEXT.name, Watcher.SCRIPT_SEARCH_CONTEXT); - contexts.put(Watcher.SCRIPT_EXECUTABLE_CONTEXT.name, Watcher.SCRIPT_EXECUTABLE_CONTEXT); + contexts.put(WatcherTransformScript.CONTEXT.name, WatcherTransformScript.CONTEXT); scriptService = new ScriptService(Settings.EMPTY, engines, contexts); } diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/VariablesTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/VariablesTests.java index 74396a3290644..4ab5b7b7b87aa 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/VariablesTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/VariablesTests.java @@ -40,7 +40,7 @@ public void testCreateCtxModel() throws Exception { .metadata(metatdata) .buildMock(); - Map model = Variables.createCtxModel(ctx, payload); + Map model = Variables.createCtxParamsMap(ctx, payload); assertThat(model, notNullValue()); assertThat(model.size(), is(1)); diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SearchInputTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SearchInputTests.java index 6d7f4bef213f7..b66a70c23afa4 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SearchInputTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SearchInputTests.java @@ -42,6 +42,7 @@ import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateRequest; import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateService; import org.elasticsearch.xpack.watcher.test.WatcherTestUtils; +import org.elasticsearch.xpack.watcher.transform.script.WatcherTransformScript; import org.junit.Before; import org.mockito.ArgumentCaptor; @@ -76,7 +77,7 @@ public void setup() { Map> contexts = new HashMap<>(); contexts.put(Watcher.SCRIPT_TEMPLATE_CONTEXT.name, Watcher.SCRIPT_TEMPLATE_CONTEXT); contexts.put(Watcher.SCRIPT_SEARCH_CONTEXT.name, Watcher.SCRIPT_SEARCH_CONTEXT); - contexts.put(Watcher.SCRIPT_EXECUTABLE_CONTEXT.name, Watcher.SCRIPT_EXECUTABLE_CONTEXT); + contexts.put(WatcherTransformScript.CONTEXT.name, WatcherTransformScript.CONTEXT); scriptService = new ScriptService(Settings.EMPTY, engines, contexts); ThreadPool threadPool = mock(ThreadPool.class); diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/script/ScriptTransformTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/script/ScriptTransformTests.java index bc79561f726c9..993702f161fd8 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/script/ScriptTransformTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/script/ScriptTransformTests.java @@ -8,7 +8,6 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptException; @@ -49,21 +48,21 @@ public void testExecuteMapValue() throws Exception { ScriptType type = randomFrom(ScriptType.values()); Map params = Collections.emptyMap(); Script script = new Script(type, type == ScriptType.STORED ? null : "_lang", "_script", params); - ExecutableScript.Factory factory = mock(ExecutableScript.Factory.class); - when(service.compile(script, Watcher.SCRIPT_EXECUTABLE_CONTEXT)).thenReturn(factory); + WatcherTransformScript.Factory factory = mock(WatcherTransformScript.Factory.class); + when(service.compile(script, WatcherTransformScript.CONTEXT)).thenReturn(factory); ExecutableScriptTransform transform = new ExecutableScriptTransform(new ScriptTransform(script), logger, service); WatchExecutionContext ctx = mockExecutionContext("_name", Payload.EMPTY); Payload payload = new Payload.Simple("key", "value"); - Map model = Variables.createCtxModel(ctx, payload); + Map model = Variables.createCtxParamsMap(ctx, payload); Map transformed = singletonMap("key", "value"); - ExecutableScript executable = mock(ExecutableScript.class); - when(executable.run()).thenReturn(transformed); - when(factory.newInstance(model)).thenReturn(executable); + WatcherTransformScript executable = mock(WatcherTransformScript.class); + when(executable.execute()).thenReturn(transformed); + when(factory.newInstance(model, ctx, payload)).thenReturn(executable); Transform.Result result = transform.execute(ctx, payload); assertThat(result, notNullValue()); @@ -77,19 +76,19 @@ public void testExecuteMapValueFailure() throws Exception { ScriptType type = randomFrom(ScriptType.values()); Map params = Collections.emptyMap(); Script script = new Script(type, type == ScriptType.STORED ? null : "_lang", "_script", params); - ExecutableScript.Factory factory = mock(ExecutableScript.Factory.class); - when(service.compile(script, Watcher.SCRIPT_EXECUTABLE_CONTEXT)).thenReturn(factory); + WatcherTransformScript.Factory factory = mock(WatcherTransformScript.Factory.class); + when(service.compile(script, WatcherTransformScript.CONTEXT)).thenReturn(factory); ExecutableScriptTransform transform = new ExecutableScriptTransform(new ScriptTransform(script), logger, service); WatchExecutionContext ctx = mockExecutionContext("_name", Payload.EMPTY); Payload payload = new Payload.Simple("key", "value"); - Map model = Variables.createCtxModel(ctx, payload); + Map model = Variables.createCtxParamsMap(ctx, payload); - ExecutableScript executable = mock(ExecutableScript.class); - when(executable.run()).thenThrow(new RuntimeException("_error")); - when(factory.newInstance(model)).thenReturn(executable); + WatcherTransformScript executable = mock(WatcherTransformScript.class); + when(executable.execute()).thenThrow(new RuntimeException("_error")); + when(factory.newInstance(model, ctx, payload)).thenReturn(executable); Transform.Result result = transform.execute(ctx, payload); assertThat(result, notNullValue()); @@ -103,20 +102,20 @@ public void testExecuteNonMapValue() throws Exception { ScriptType type = randomFrom(ScriptType.values()); Map params = Collections.emptyMap(); Script script = new Script(type, type == ScriptType.STORED ? null : "_lang", "_script", params); - ExecutableScript.Factory factory = mock(ExecutableScript.Factory.class); - when(service.compile(script, Watcher.SCRIPT_EXECUTABLE_CONTEXT)).thenReturn(factory); + WatcherTransformScript.Factory factory = mock(WatcherTransformScript.Factory.class); + when(service.compile(script, WatcherTransformScript.CONTEXT)).thenReturn(factory); ExecutableScriptTransform transform = new ExecutableScriptTransform(new ScriptTransform(script), logger, service); WatchExecutionContext ctx = mockExecutionContext("_name", Payload.EMPTY); Payload payload = new Payload.Simple("key", "value"); - Map model = Variables.createCtxModel(ctx, payload); + Map model = Variables.createCtxParamsMap(ctx, payload); - ExecutableScript executable = mock(ExecutableScript.class); + WatcherTransformScript executable = mock(WatcherTransformScript.class); Object value = randomFrom("value", 1, new String[] { "value" }, Collections.singletonList("value"), singleton("value")); - when(executable.run()).thenReturn(value); - when(factory.newInstance(model)).thenReturn(executable); + when(executable.execute()).thenReturn(value); + when(factory.newInstance(model, ctx, payload)).thenReturn(executable); Transform.Result result = transform.execute(ctx, payload); assertThat(result, notNullValue()); @@ -158,7 +157,7 @@ public void testScriptConditionParserBadScript() throws Exception { String errorMessage = "expected error message"; ScriptException scriptException = new ScriptException(errorMessage, new RuntimeException("foo"), Collections.emptyList(), "whatever", "whatever"); - when(scriptService.compile(anyObject(), eq(Watcher.SCRIPT_EXECUTABLE_CONTEXT))).thenThrow(scriptException); + when(scriptService.compile(anyObject(), eq(WatcherTransformScript.CONTEXT))).thenThrow(scriptException); ScriptTransformFactory transformFactory = new ScriptTransformFactory(Settings.builder().build(), scriptService); @@ -205,7 +204,7 @@ public static ScriptService createScriptService() throws Exception { .put("path.home", createTempDir()) .build(); Map contexts = new HashMap<>(ScriptModule.CORE_CONTEXTS); - contexts.put(Watcher.SCRIPT_EXECUTABLE_CONTEXT.name, Watcher.SCRIPT_EXECUTABLE_CONTEXT); + contexts.put(WatcherTransformScript.CONTEXT.name, WatcherTransformScript.CONTEXT); contexts.put(Watcher.SCRIPT_TEMPLATE_CONTEXT.name, Watcher.SCRIPT_TEMPLATE_CONTEXT); return new ScriptService(settings, Collections.emptyMap(), Collections.emptyMap()); } From 3ba033145659d8272b83b3375f25ae158bfff235 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Tue, 25 Sep 2018 14:03:27 -0700 Subject: [PATCH 02/12] clarify method uses with javadocs --- .../java/org/elasticsearch/xpack/watcher/support/Variables.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/Variables.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/Variables.java index fc82e51352ddf..cf3c9f8103924 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/Variables.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/Variables.java @@ -22,12 +22,14 @@ public final class Variables { public static final String METADATA = "metadata"; public static final String VARS = "vars"; + /** Creates a ctx map and puts it into the returned map as "ctx". */ public static Map createCtxParamsMap(WatchExecutionContext ctx, Payload payload) { Map model = new HashMap<>(); model.put(CTX, createCtx(ctx, payload)); return model; } + /** Creates a ctx map. */ public static Map createCtx(WatchExecutionContext ctx, Payload payload) { Map ctxModel = new HashMap<>(); ctxModel.put(ID, ctx.id().value()); From 0db54d15cb56eddd897ea1d5ac13838d323ffc18 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Tue, 25 Sep 2018 14:47:46 -0700 Subject: [PATCH 03/12] fix license headers --- .../condition/WatcherConditionScript.java | 20 +++---------------- .../script/WatcherTransformScript.java | 20 +++---------------- 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java index a2a2b9c722681..23350b2be05c6 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java @@ -1,22 +1,8 @@ /* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. */ - package org.elasticsearch.xpack.watcher.condition; import org.elasticsearch.script.ParameterMap; diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/WatcherTransformScript.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/WatcherTransformScript.java index adeeb5be67425..8191f7cbae5e0 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/WatcherTransformScript.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/WatcherTransformScript.java @@ -1,22 +1,8 @@ /* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. */ - package org.elasticsearch.xpack.watcher.transform.script; import org.elasticsearch.script.ParameterMap; From 5cb67bd20bf79f71efa26d2a992ce4e5bba1aab6 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Tue, 25 Sep 2018 14:48:37 -0700 Subject: [PATCH 04/12] fix grammar --- .../xpack/watcher/condition/WatcherConditionScript.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java index 23350b2be05c6..5d3636151d374 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java @@ -32,7 +32,7 @@ public abstract class WatcherConditionScript { } private final Map params; - // TODO: ctx should have its members extracted into execute parameters, but it needs to be a member bwc access in params + // TODO: ctx should have its members extracted into execute parameters, but it needs to be a member for bwc access in params private final Map ctx; public WatcherConditionScript(Map params, WatchExecutionContext watcherContext) { From b386aa19f19da5a95322e9004868b1c94f9f29d1 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Tue, 25 Sep 2018 22:24:06 -0700 Subject: [PATCH 05/12] add empty parameters to new scripts --- .../xpack/watcher/condition/WatcherConditionScript.java | 1 + .../xpack/watcher/transform/script/WatcherTransformScript.java | 1 + 2 files changed, 2 insertions(+) diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java index 5d3636151d374..1148cc6a58eb5 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/WatcherConditionScript.java @@ -18,6 +18,7 @@ * A script to determine whether a watch should be run. */ public abstract class WatcherConditionScript { + public static final String[] PARAMETERS = {}; private static final Map DEPRECATIONS; diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/WatcherTransformScript.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/WatcherTransformScript.java index 8191f7cbae5e0..6d84c32578bc0 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/WatcherTransformScript.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transform/script/WatcherTransformScript.java @@ -19,6 +19,7 @@ * A script to transform the results of a watch execution. */ public abstract class WatcherTransformScript { + public static final String[] PARAMETERS = {}; private static final Map DEPRECATIONS; From cb088709caba0bdf7b0626bdcf501572cfc3ff91 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Wed, 26 Sep 2018 14:28:08 -0700 Subject: [PATCH 06/12] fix bad merge --- .../xpack/watcher/condition/ScriptCondition.java | 6 +++--- .../watcher/condition/AlwaysConditionTests.java | 3 +-- .../watcher/condition/ScriptConditionTests.java | 15 ++++++--------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/ScriptCondition.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/ScriptCondition.java index a3ddf0ff1c2e9..19307569ce06b 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/ScriptCondition.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/condition/ScriptCondition.java @@ -30,10 +30,10 @@ public final class ScriptCondition implements ExecutableCondition { public ScriptCondition(Script script) { this.script = script; - scriptFactory = null; + this.scriptFactory = null; } - ScriptCondition(Script script, ExecutableScript.Factory scriptFactory) { + ScriptCondition(Script script, ScriptService scriptService) { this.script = script; this.scriptFactory = scriptService.compile(script, WatcherConditionScript.CONTEXT); } @@ -45,7 +45,7 @@ public Script getScript() { public static ScriptCondition parse(ScriptService scriptService, String watchId, XContentParser parser) throws IOException { try { Script script = Script.parse(parser); - return new ScriptCondition(script, scriptService.compile(script, Watcher.SCRIPT_EXECUTABLE_CONTEXT)); + return new ScriptCondition(script, scriptService); } catch (ElasticsearchParseException pe) { throw new ElasticsearchParseException("could not parse [{}] condition for watch [{}]. failed to parse script", pe, TYPE, watchId); diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/AlwaysConditionTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/AlwaysConditionTests.java index c29452302c0ab..20bf83ef4ed77 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/AlwaysConditionTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/AlwaysConditionTests.java @@ -12,7 +12,6 @@ import org.elasticsearch.script.ScriptService; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.core.watcher.condition.ExecutableCondition; -import org.elasticsearch.xpack.watcher.Watcher; import java.time.Clock; @@ -56,7 +55,7 @@ public static ExecutableCondition randomCondition(ScriptService scriptService) { switch (type) { case ScriptCondition.TYPE: Script mockScript = mockScript("_script"); - return new ScriptCondition(mockScript, scriptService.compile(mockScript, Watcher.SCRIPT_EXECUTABLE_CONTEXT)); + return new ScriptCondition(mockScript, scriptService); case CompareCondition.TYPE: return new CompareCondition("_path", randomFrom(CompareCondition.Op.values()), randomFrom(5, "3"), Clock.systemUTC()); diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java index 47fd5f5009906..71e547a08d4e4 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java @@ -94,8 +94,7 @@ public void init() throws IOException { } public void testExecute() throws Exception { - Script script = mockScript("ctx.payload.hits.total > 1"); - ScriptCondition condition = new ScriptCondition(script, scriptService.compile(script, Watcher.SCRIPT_EXECUTABLE_CONTEXT)); + ScriptCondition condition = new ScriptCondition(mockScript("ctx.payload.hits.total > 1"), scriptService); SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 0, 500L, ShardSearchFailure.EMPTY_ARRAY, SearchResponse.Clusters.EMPTY); WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response)); @@ -104,7 +103,7 @@ public void testExecute() throws Exception { public void testExecuteMergedParams() throws Exception { Script script = new Script(ScriptType.INLINE, "mockscript", "ctx.payload.hits.total > threshold", singletonMap("threshold", 1)); - ScriptCondition executable = new ScriptCondition(script, scriptService.compile(script, Watcher.SCRIPT_EXECUTABLE_CONTEXT)); + ScriptCondition executable = new ScriptCondition(script, scriptService); SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 0, 500L, ShardSearchFailure.EMPTY_ARRAY, SearchResponse.Clusters.EMPTY); WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response)); @@ -182,9 +181,8 @@ public void testScriptConditionParser_badLang() throws Exception { } public void testScriptConditionThrowException() throws Exception { - Script script = mockScript("null.foo"); ScriptCondition condition = new ScriptCondition( - script, scriptService.compile(script, Watcher.SCRIPT_EXECUTABLE_CONTEXT)); + mockScript("null.foo"), scriptService); SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 0, 500L, ShardSearchFailure.EMPTY_ARRAY, SearchResponse.Clusters.EMPTY); WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response)); @@ -193,8 +191,7 @@ public void testScriptConditionThrowException() throws Exception { } public void testScriptConditionReturnObjectThrowsException() throws Exception { - Script script = mockScript("return new Object()"); - ScriptCondition condition = new ScriptCondition(script, scriptService.compile(script, Watcher.SCRIPT_EXECUTABLE_CONTEXT)); + ScriptCondition condition = new ScriptCondition(mockScript("return new Object()"), scriptService); SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 0, 500L, ShardSearchFailure.EMPTY_ARRAY, SearchResponse.Clusters.EMPTY); WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response)); @@ -204,8 +201,8 @@ public void testScriptConditionReturnObjectThrowsException() throws Exception { } public void testScriptConditionAccessCtx() throws Exception { - Script script = mockScript("ctx.trigger.scheduled_time.getMillis() < new Date().time"); - ScriptCondition condition = new ScriptCondition(script, scriptService.compile(script, Watcher.SCRIPT_EXECUTABLE_CONTEXT)); + ScriptCondition condition = new ScriptCondition(mockScript("ctx.trigger.scheduled_time.getMillis() < new Date().time"), + scriptService); SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 0, 500L, ShardSearchFailure.EMPTY_ARRAY, SearchResponse.Clusters.EMPTY); WatchExecutionContext ctx = mockExecutionContext("_name", new DateTime(DateTimeZone.UTC), new Payload.XContent(response)); From b05f1d88863be63eab0daf0030c48c43be04ff7f Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Wed, 26 Sep 2018 17:49:53 -0700 Subject: [PATCH 07/12] Tests: Add support for custom contexts to mock scripts This commit adds the ability to plug in compilation of custom contexts in mock script engine. This is needed for testing plugins which add custom contexts like watcher. --- .../elasticsearch/script/MockScriptEngine.java | 16 ++++++++++++++-- .../elasticsearch/script/MockScriptPlugin.java | 7 ++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/test/framework/src/main/java/org/elasticsearch/script/MockScriptEngine.java b/test/framework/src/main/java/org/elasticsearch/script/MockScriptEngine.java index 1b609e8171195..e81c9f95ba2f6 100644 --- a/test/framework/src/main/java/org/elasticsearch/script/MockScriptEngine.java +++ b/test/framework/src/main/java/org/elasticsearch/script/MockScriptEngine.java @@ -53,18 +53,26 @@ */ public class MockScriptEngine implements ScriptEngine { + /** A non-typed compiler for a single custom context */ + public interface ContextCompiler { + Object compile(Function, Object> script, Map params); + } + public static final String NAME = "mockscript"; private final String type; private final Map, Object>> scripts; + private final Map, ContextCompiler> contexts; - public MockScriptEngine(String type, Map, Object>> scripts) { + public MockScriptEngine(String type, Map, Object>> scripts, + Map, ContextCompiler> contexts) { this.type = type; this.scripts = Collections.unmodifiableMap(scripts); + this.contexts = Collections.unmodifiableMap(contexts); } public MockScriptEngine() { - this(NAME, Collections.emptyMap()); + this(NAME, Collections.emptyMap(), Collections.emptyMap()); } @Override @@ -198,6 +206,10 @@ public String execute() { ScriptedMetricAggContexts.ReduceScript.Factory factory = mockCompiled::createMetricAggReduceScript; return context.factoryClazz.cast(factory); } + ContextCompiler compiler = contexts.get(context); + if (compiler != null) { + return context.factoryClazz.cast(compiler.compile(script, params)); + } throw new IllegalArgumentException("mock script engine does not know how to handle context [" + context.name + "]"); } diff --git a/test/framework/src/main/java/org/elasticsearch/script/MockScriptPlugin.java b/test/framework/src/main/java/org/elasticsearch/script/MockScriptPlugin.java index cd951a3b53f5c..34aca79ec4725 100644 --- a/test/framework/src/main/java/org/elasticsearch/script/MockScriptPlugin.java +++ b/test/framework/src/main/java/org/elasticsearch/script/MockScriptPlugin.java @@ -24,6 +24,7 @@ import org.elasticsearch.plugins.ScriptPlugin; import java.util.Collection; +import java.util.Collections; import java.util.Map; import java.util.function.Function; @@ -36,11 +37,15 @@ public abstract class MockScriptPlugin extends Plugin implements ScriptPlugin { @Override public ScriptEngine getScriptEngine(Settings settings, Collection> contexts) { - return new MockScriptEngine(pluginScriptLang(), pluginScripts()); + return new MockScriptEngine(pluginScriptLang(), pluginScripts(), pluginContextCompilers()); } protected abstract Map, Object>> pluginScripts(); + protected Map, MockScriptEngine.ContextCompiler> pluginContextCompilers() { + return Collections.emptyMap(); + } + public String pluginScriptLang() { return NAME; } From 32efc36f13c881d67cd8437e2b4231156eefe8ae Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Wed, 26 Sep 2018 18:23:18 -0700 Subject: [PATCH 08/12] add contexts to mock script negine --- .../ingest/common/ScriptProcessorTests.java | 11 ++++---- .../action/update/UpdateRequestTests.java | 2 +- .../ingest/ConditionalProcessorTests.java | 21 +++++++++------- .../script/ScriptServiceTests.java | 4 +-- .../metrics/InternalScriptedMetricTests.java | 5 ++-- .../ScriptedMetricAggregatorTests.java | 4 +-- .../search/sort/AbstractSortTestCase.java | 2 +- .../ingest/TestTemplateService.java | 3 +-- .../org/elasticsearch/test/ESTestCase.java | 2 +- .../xpack/upgrade/IndexUpgradeTasksIT.java | 2 +- .../condition/ScriptConditionTests.java | 2 +- .../input/transform/TransformInputTests.java | 3 ++- .../ExecutionVarsIntegrationTests.java | 25 +++++++++++++++++++ .../integration/SearchTransformTests.java | 2 +- 14 files changed, 57 insertions(+), 31 deletions(-) diff --git a/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/ScriptProcessorTests.java b/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/ScriptProcessorTests.java index 72bc337e9c9f7..10fcf5fe602ad 100644 --- a/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/ScriptProcessorTests.java +++ b/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/ScriptProcessorTests.java @@ -19,10 +19,6 @@ package org.elasticsearch.ingest.common; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - import org.elasticsearch.common.settings.Settings; import org.elasticsearch.ingest.IngestDocument; import org.elasticsearch.ingest.RandomDocumentPicks; @@ -33,6 +29,10 @@ import org.elasticsearch.script.ScriptType; import org.elasticsearch.test.ESTestCase; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + import static org.hamcrest.Matchers.hasKey; import static org.hamcrest.core.Is.is; @@ -52,7 +52,8 @@ Script.DEFAULT_SCRIPT_LANG, new MockScriptEngine( ctx.put("bytes_total", randomBytesTotal); return null; } - ) + ), + Collections.emptyMap() ) ), new HashMap<>(ScriptModule.CORE_CONTEXTS) diff --git a/server/src/test/java/org/elasticsearch/action/update/UpdateRequestTests.java b/server/src/test/java/org/elasticsearch/action/update/UpdateRequestTests.java index 8e6db7d776191..ff7697745da76 100644 --- a/server/src/test/java/org/elasticsearch/action/update/UpdateRequestTests.java +++ b/server/src/test/java/org/elasticsearch/action/update/UpdateRequestTests.java @@ -132,7 +132,7 @@ public void setUp() throws Exception { return null; }); scripts.put("return", vars -> null); - final MockScriptEngine engine = new MockScriptEngine("mock", scripts); + final MockScriptEngine engine = new MockScriptEngine("mock", scripts, Collections.emptyMap()); Map engines = Collections.singletonMap(engine.getType(), engine); ScriptService scriptService = new ScriptService(baseSettings, engines, ScriptModule.CORE_CONTEXTS); final Settings settings = settings(Version.CURRENT).build(); diff --git a/server/src/test/java/org/elasticsearch/ingest/ConditionalProcessorTests.java b/server/src/test/java/org/elasticsearch/ingest/ConditionalProcessorTests.java index 12b4078ddf8bb..c7d4dfa4e68cd 100644 --- a/server/src/test/java/org/elasticsearch/ingest/ConditionalProcessorTests.java +++ b/server/src/test/java/org/elasticsearch/ingest/ConditionalProcessorTests.java @@ -19,13 +19,6 @@ package org.elasticsearch.ingest; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.script.MockScriptEngine; import org.elasticsearch.script.Script; @@ -34,6 +27,14 @@ import org.elasticsearch.script.ScriptType; import org.elasticsearch.test.ESTestCase; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; + import static org.hamcrest.Matchers.hasKey; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.not; @@ -52,7 +53,8 @@ public void testChecksCondition() throws Exception { Script.DEFAULT_SCRIPT_LANG, Collections.singletonMap( scriptName, ctx -> trueValue.equals(ctx.get(conditionalField)) - ) + ), + Collections.emptyMap() ) ), new HashMap<>(ScriptModule.CORE_CONTEXTS) @@ -120,7 +122,8 @@ private static void assertMutatingCtxThrows(Consumer> mutati } return false; } - ) + ), + Collections.emptyMap() ) ), new HashMap<>(ScriptModule.CORE_CONTEXTS) diff --git a/server/src/test/java/org/elasticsearch/script/ScriptServiceTests.java b/server/src/test/java/org/elasticsearch/script/ScriptServiceTests.java index ea8b6a9223412..fcb868c0e0e84 100644 --- a/server/src/test/java/org/elasticsearch/script/ScriptServiceTests.java +++ b/server/src/test/java/org/elasticsearch/script/ScriptServiceTests.java @@ -66,12 +66,12 @@ public void setup() throws IOException { scripts.put(i + "+" + i, p -> null); // only care about compilation, not execution } scripts.put("script", p -> null); - scriptEngine = new MockScriptEngine(Script.DEFAULT_SCRIPT_LANG, scripts); + scriptEngine = new MockScriptEngine(Script.DEFAULT_SCRIPT_LANG, scripts, Collections.emptyMap()); //prevent duplicates using map contexts = new HashMap<>(ScriptModule.CORE_CONTEXTS); engines = new HashMap<>(); engines.put(scriptEngine.getType(), scriptEngine); - engines.put("test", new MockScriptEngine("test", scripts)); + engines.put("test", new MockScriptEngine("test", scripts, Collections.emptyMap())); logger.info("--> setup script service"); } diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/InternalScriptedMetricTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/InternalScriptedMetricTests.java index 89f42355f204a..d1918c170ed37 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/InternalScriptedMetricTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/InternalScriptedMetricTests.java @@ -30,8 +30,6 @@ import org.elasticsearch.script.ScriptType; import org.elasticsearch.search.aggregations.Aggregation.CommonFields; import org.elasticsearch.search.aggregations.ParsedAggregation; -import org.elasticsearch.search.aggregations.metrics.InternalScriptedMetric; -import org.elasticsearch.search.aggregations.metrics.ParsedScriptedMetric; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import org.elasticsearch.test.InternalAggregationTestCase; @@ -118,7 +116,8 @@ protected ScriptService mockScriptService() { // mock script always retuns the size of the input aggs list as result @SuppressWarnings("unchecked") MockScriptEngine scriptEngine = new MockScriptEngine(MockScriptEngine.NAME, - Collections.singletonMap(REDUCE_SCRIPT_NAME, script -> ((List) script.get("states")).size())); + Collections.singletonMap(REDUCE_SCRIPT_NAME, script -> ((List) script.get("states")).size()), + Collections.emptyMap()); Map engines = Collections.singletonMap(scriptEngine.getType(), scriptEngine); return new ScriptService(Settings.EMPTY, engines, ScriptModule.CORE_CONTEXTS); } diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ScriptedMetricAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ScriptedMetricAggregatorTests.java index 56b8938b6e54b..34ef4b9b93c98 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ScriptedMetricAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ScriptedMetricAggregatorTests.java @@ -35,8 +35,6 @@ import org.elasticsearch.script.ScriptService; import org.elasticsearch.script.ScriptType; import org.elasticsearch.search.aggregations.AggregatorTestCase; -import org.elasticsearch.search.aggregations.metrics.ScriptedMetric; -import org.elasticsearch.search.aggregations.metrics.ScriptedMetricAggregationBuilder; import org.junit.BeforeClass; import java.io.IOException; @@ -345,7 +343,7 @@ public void testSelfReferencingAggStateAfterCombine() throws IOException { */ @Override protected QueryShardContext queryShardContextMock(MapperService mapperService) { - MockScriptEngine scriptEngine = new MockScriptEngine(MockScriptEngine.NAME, SCRIPTS); + MockScriptEngine scriptEngine = new MockScriptEngine(MockScriptEngine.NAME, SCRIPTS, Collections.emptyMap()); Map engines = Collections.singletonMap(scriptEngine.getType(), scriptEngine); ScriptService scriptService = new ScriptService(Settings.EMPTY, engines, ScriptModule.CORE_CONTEXTS); return new QueryShardContext(0, mapperService.getIndexSettings(), null, null, mapperService, null, scriptService, diff --git a/server/src/test/java/org/elasticsearch/search/sort/AbstractSortTestCase.java b/server/src/test/java/org/elasticsearch/search/sort/AbstractSortTestCase.java index 2285af3ec46c0..e301e8c11c3ad 100644 --- a/server/src/test/java/org/elasticsearch/search/sort/AbstractSortTestCase.java +++ b/server/src/test/java/org/elasticsearch/search/sort/AbstractSortTestCase.java @@ -84,7 +84,7 @@ public static void init() { .put(Environment.PATH_HOME_SETTING.getKey(), createTempDir().toString()) .build(); Map, Object>> scripts = Collections.singletonMap(MOCK_SCRIPT_NAME, p -> null); - ScriptEngine engine = new MockScriptEngine(MockScriptEngine.NAME, scripts); + ScriptEngine engine = new MockScriptEngine(MockScriptEngine.NAME, scripts, Collections.emptyMap()); scriptService = new ScriptService(baseSettings, Collections.singletonMap(engine.getType(), engine), ScriptModule.CORE_CONTEXTS); SearchModule searchModule = new SearchModule(Settings.EMPTY, false, emptyList()); diff --git a/test/framework/src/main/java/org/elasticsearch/ingest/TestTemplateService.java b/test/framework/src/main/java/org/elasticsearch/ingest/TestTemplateService.java index 4777d7c4ef24a..5bbf39d8fdc17 100644 --- a/test/framework/src/main/java/org/elasticsearch/ingest/TestTemplateService.java +++ b/test/framework/src/main/java/org/elasticsearch/ingest/TestTemplateService.java @@ -43,8 +43,7 @@ public static ScriptService instance(boolean compilationException) { } private TestTemplateService(boolean compilationException) { - super(Settings.EMPTY, Collections.singletonMap(DEFAULT_TEMPLATE_LANG, - new MockScriptEngine(MockScriptEngine.NAME, Collections.emptyMap())), Collections.emptyMap()); + super(Settings.EMPTY, Collections.singletonMap(DEFAULT_TEMPLATE_LANG, new MockScriptEngine()), Collections.emptyMap()); this.compilationException = compilationException; } diff --git a/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java index ffa7c601184b3..d5cf798682aef 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java @@ -1384,7 +1384,7 @@ public static ScriptModule newTestScriptModule() { return new ScriptModule(Settings.EMPTY, singletonList(new ScriptPlugin() { @Override public ScriptEngine getScriptEngine(Settings settings, Collection> contexts) { - return new MockScriptEngine(MockScriptEngine.NAME, Collections.singletonMap("1", script -> "1")); + return new MockScriptEngine(MockScriptEngine.NAME, Collections.singletonMap("1", script -> "1"), Collections.emptyMap()); } })); } diff --git a/x-pack/plugin/upgrade/src/test/java/org/elasticsearch/xpack/upgrade/IndexUpgradeTasksIT.java b/x-pack/plugin/upgrade/src/test/java/org/elasticsearch/xpack/upgrade/IndexUpgradeTasksIT.java index 7605af041e67c..1cc6ce8e54777 100644 --- a/x-pack/plugin/upgrade/src/test/java/org/elasticsearch/xpack/upgrade/IndexUpgradeTasksIT.java +++ b/x-pack/plugin/upgrade/src/test/java/org/elasticsearch/xpack/upgrade/IndexUpgradeTasksIT.java @@ -88,7 +88,7 @@ public static class MockUpgradePlugin extends Plugin implements ScriptPlugin, Ac @Override public ScriptEngine getScriptEngine(Settings settings, Collection> contexts) { - return new MockScriptEngine(pluginScriptLang(), pluginScripts()); + return new MockScriptEngine(pluginScriptLang(), pluginScripts(), Collections.emptyMap()); } public String pluginScriptLang() { diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java index 71e547a08d4e4..6ff04853e84f3 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java @@ -83,7 +83,7 @@ public void init() throws IOException { return total > threshold; }); - ScriptEngine engine = new MockScriptEngine(MockScriptEngine.NAME, scripts); + ScriptEngine engine = new MockScriptEngine(MockScriptEngine.NAME, scripts, Collections.emptyMap()); scriptService = new ScriptService(Settings.EMPTY, Collections.singletonMap(engine.getType(), engine), Collections.singletonMap(WatcherTransformScript.CONTEXT.name, WatcherTransformScript.CONTEXT)); diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/input/transform/TransformInputTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/input/transform/TransformInputTests.java index 9ebde46148dbe..992cc98e471c7 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/input/transform/TransformInputTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/input/transform/TransformInputTests.java @@ -48,7 +48,8 @@ public class TransformInputTests extends ESTestCase { @Before public void setupScriptService() { Map engines = new HashMap<>(); - engines.put(MockScriptEngine.NAME, new MockScriptEngine(MockScriptEngine.NAME, Collections.singletonMap("1", s -> "2"))); + engines.put(MockScriptEngine.NAME, + new MockScriptEngine(MockScriptEngine.NAME, Collections.singletonMap("1", s -> "2"), Collections.emptyMap())); Map> contexts = new HashMap<>(); contexts.put(Watcher.SCRIPT_TEMPLATE_CONTEXT.name, Watcher.SCRIPT_TEMPLATE_CONTEXT); contexts.put(Watcher.SCRIPT_SEARCH_CONTEXT.name, Watcher.SCRIPT_SEARCH_CONTEXT); diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/ExecutionVarsIntegrationTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/ExecutionVarsIntegrationTests.java index 0b3c0fc28ec05..b3c96fed39d63 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/ExecutionVarsIntegrationTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/ExecutionVarsIntegrationTests.java @@ -9,13 +9,17 @@ import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.protocol.xpack.watcher.PutWatchResponse; +import org.elasticsearch.script.MockScriptEngine; import org.elasticsearch.script.MockScriptPlugin; +import org.elasticsearch.script.ScriptContext; import org.elasticsearch.xpack.core.watcher.client.WatcherClient; import org.elasticsearch.xpack.core.watcher.support.xcontent.ObjectPath; import org.elasticsearch.xpack.core.watcher.support.xcontent.XContentSource; import org.elasticsearch.xpack.core.watcher.transport.actions.execute.ExecuteWatchResponse; import org.elasticsearch.xpack.watcher.condition.ScriptCondition; +import org.elasticsearch.xpack.watcher.condition.WatcherConditionScript; import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase; +import org.elasticsearch.xpack.watcher.transform.script.WatcherTransformScript; import org.hamcrest.Matcher; import java.util.HashMap; @@ -105,6 +109,27 @@ protected Map, Object>> pluginScripts() { return scripts; } + + protected Map, MockScriptEngine.ContextCompiler> pluginContextCompilers() { + HashMap, MockScriptEngine.ContextCompiler> compilers = new HashMap<>(); + compilers.put(WatcherConditionScript.CONTEXT, (script, options) -> + (WatcherConditionScript.Factory) (params, watcherContext) -> + new WatcherConditionScript(params, watcherContext) { + @Override + public boolean execute() { + return (boolean) script.apply(getParams()); + } + }); + compilers.put(WatcherTransformScript.CONTEXT, (script, options) -> + (WatcherTransformScript.Factory) (params, watcherContext, payload) -> + new WatcherTransformScript(params, watcherContext, payload) { + @Override + public Object execute() { + return script.apply(getParams()); + } + }); + return compilers; + } } public void testVars() throws Exception { diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SearchTransformTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SearchTransformTests.java index 10c61677a4c42..72bc71cdb08c2 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SearchTransformTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/SearchTransformTests.java @@ -70,7 +70,7 @@ public void testParser() throws Exception { XContentParser parser = createParser(builder); parser.nextToken(); - final MockScriptEngine engine = new MockScriptEngine("mock", Collections.emptyMap()); + final MockScriptEngine engine = new MockScriptEngine("mock", Collections.emptyMap(), Collections.emptyMap()); Map engines = Collections.singletonMap(engine.getType(), engine); ScriptService scriptService = new ScriptService(Settings.EMPTY, engines, ScriptModule.CORE_CONTEXTS); From e1e0490e62f48705238074e79da83db3e84b4545 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Thu, 27 Sep 2018 09:04:41 -0700 Subject: [PATCH 09/12] add deprecation warning tests --- .../condition/ScriptConditionTests.java | 22 +++++++++++++++++++ .../script/ScriptTransformTests.java | 20 +++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java index 6ff04853e84f3..be074b94a005c 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java @@ -30,7 +30,10 @@ import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.core.watcher.condition.ExecutableCondition; import org.elasticsearch.xpack.core.watcher.execution.WatchExecutionContext; +import org.elasticsearch.xpack.core.watcher.execution.Wid; +import org.elasticsearch.xpack.core.watcher.trigger.TriggerEvent; import org.elasticsearch.xpack.core.watcher.watch.Payload; +import org.elasticsearch.xpack.core.watcher.watch.Watch; import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase; import org.elasticsearch.xpack.watcher.transform.script.WatcherTransformScript; import org.joda.time.DateTime; @@ -51,6 +54,8 @@ import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.mockExecutionContext; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class ScriptConditionTests extends ESTestCase { @@ -210,6 +215,23 @@ public void testScriptConditionAccessCtx() throws Exception { assertThat(condition.execute(ctx).met(), is(true)); } + public void testParamsCtxDeprecated() throws Exception { + WatchExecutionContext watcherContext = mock(WatchExecutionContext.class); + when(watcherContext.id()).thenReturn(mock(Wid.class)); + when(watcherContext.watch()).thenReturn(mock(Watch.class)); + when(watcherContext.triggerEvent()).thenReturn(mock(TriggerEvent.class)); + WatcherConditionScript watcherScript = new WatcherConditionScript(Collections.emptyMap(), watcherContext) { + @Override + public boolean execute() { + assertThat(getParams().get("ctx"), is(getCtx())); + return true; + } + }; + watcherScript.execute(); + assertWarnings("Accessing variable [ctx] via [params.ctx] from within a watcher_condition script " + + "is deprecated in favor of directly accessing [ctx]."); + } + private static XContentBuilder createConditionContent(String script, String scriptLang, ScriptType scriptType) throws IOException { XContentBuilder builder = jsonBuilder(); if (scriptType == null) { diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/script/ScriptTransformTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/script/ScriptTransformTests.java index 993702f161fd8..ba5d225792b1d 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/script/ScriptTransformTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/script/ScriptTransformTests.java @@ -16,8 +16,11 @@ import org.elasticsearch.script.ScriptType; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.core.watcher.execution.WatchExecutionContext; +import org.elasticsearch.xpack.core.watcher.execution.Wid; import org.elasticsearch.xpack.core.watcher.transform.Transform; +import org.elasticsearch.xpack.core.watcher.trigger.TriggerEvent; import org.elasticsearch.xpack.core.watcher.watch.Payload; +import org.elasticsearch.xpack.core.watcher.watch.Watch; import org.elasticsearch.xpack.watcher.Watcher; import org.elasticsearch.xpack.watcher.support.Variables; @@ -190,6 +193,23 @@ public void testScriptConditionParserBadLang() throws Exception { assertThat(e.getMessage(), containsString("script_lang not supported [not_a_valid_lang]")); } + public void testParamsCtxDeprecated() throws Exception { + WatchExecutionContext watcherContext = mock(WatchExecutionContext.class); + when(watcherContext.id()).thenReturn(mock(Wid.class)); + when(watcherContext.watch()).thenReturn(mock(Watch.class)); + when(watcherContext.triggerEvent()).thenReturn(mock(TriggerEvent.class)); + Payload payload = mock(Payload.class); + WatcherTransformScript watcherScript = new WatcherTransformScript(Collections.emptyMap(), watcherContext, payload) { + @Override + public Object execute() { + return getParams().get("ctx"); + } + }; + assertThat(watcherScript.execute(), is(watcherScript.getCtx())); + assertWarnings("Accessing variable [ctx] via [params.ctx] from within a watcher_transform script " + + "is deprecated in favor of directly accessing [ctx]."); + } + static String scriptTypeField(ScriptType type) { switch (type) { case INLINE: return "source"; From 38e7b3b83b14eacc9647b4e3f0a0530d7ce88693 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Thu, 27 Sep 2018 15:45:47 -0700 Subject: [PATCH 10/12] fixup tests --- .../condition/ScriptConditionTests.java | 25 ++---- .../history/HistoryActionConditionTests.java | 3 +- .../input/transform/TransformInputTests.java | 15 +--- .../watcher/test/WatcherMockScriptPlugin.java | 88 +++++++++++++++++++ .../ExecutionVarsIntegrationTests.java | 29 +----- .../transform/TransformIntegrationTests.java | 3 +- .../script/ScriptTransformTests.java | 13 +-- 7 files changed, 104 insertions(+), 72 deletions(-) create mode 100644 x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/WatcherMockScriptPlugin.java diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java index be074b94a005c..4e8c83ecf91c7 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java @@ -13,15 +13,12 @@ import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.MetaData; -import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.script.GeneralScriptException; -import org.elasticsearch.script.MockScriptEngine; import org.elasticsearch.script.Script; -import org.elasticsearch.script.ScriptEngine; import org.elasticsearch.script.ScriptException; import org.elasticsearch.script.ScriptMetaData; import org.elasticsearch.script.ScriptService; @@ -35,7 +32,7 @@ import org.elasticsearch.xpack.core.watcher.watch.Payload; import org.elasticsearch.xpack.core.watcher.watch.Watch; import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase; -import org.elasticsearch.xpack.watcher.transform.script.WatcherTransformScript; +import org.elasticsearch.xpack.watcher.test.WatcherMockScriptPlugin; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.junit.Before; @@ -82,15 +79,13 @@ public void init() throws IOException { return total > 1; }); - scripts.put("ctx.payload.hits.total > threshold", vars -> { + scripts.put("ctx.payload.hits.total > params.threshold", vars -> { int total = (int) XContentMapValues.extractValue("ctx.payload.hits.total", vars); - int threshold = (int) XContentMapValues.extractValue("threshold", vars); + int threshold = (int) XContentMapValues.extractValue("params.threshold", vars); return total > threshold; }); - ScriptEngine engine = new MockScriptEngine(MockScriptEngine.NAME, scripts, Collections.emptyMap()); - scriptService = new ScriptService(Settings.EMPTY, Collections.singletonMap(engine.getType(), engine), - Collections.singletonMap(WatcherTransformScript.CONTEXT.name, WatcherTransformScript.CONTEXT)); + scriptService = WatcherMockScriptPlugin.newMockScriptService(scripts); ClusterState.Builder clusterState = new ClusterState.Builder(new ClusterName("_name")); clusterState.metaData(MetaData.builder().putCustom(ScriptMetaData.TYPE, new ScriptMetaData.Builder(null).build())); @@ -107,7 +102,7 @@ public void testExecute() throws Exception { } public void testExecuteMergedParams() throws Exception { - Script script = new Script(ScriptType.INLINE, "mockscript", "ctx.payload.hits.total > threshold", singletonMap("threshold", 1)); + Script script = new Script(ScriptType.INLINE, "mockscript", "ctx.payload.hits.total > params.threshold", singletonMap("threshold", 1)); ScriptCondition executable = new ScriptCondition(script, scriptService); SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 0, 500L, ShardSearchFailure.EMPTY_ARRAY, SearchResponse.Clusters.EMPTY); @@ -195,16 +190,6 @@ public void testScriptConditionThrowException() throws Exception { assertThat(exception.getMessage(), containsString("Error evaluating null.foo")); } - public void testScriptConditionReturnObjectThrowsException() throws Exception { - ScriptCondition condition = new ScriptCondition(mockScript("return new Object()"), scriptService); - SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 0, 500L, ShardSearchFailure.EMPTY_ARRAY, - SearchResponse.Clusters.EMPTY); - WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response)); - Exception exception = expectThrows(IllegalStateException.class, () -> condition.execute(ctx)); - assertThat(exception.getMessage(), - containsString("condition [script] must return a boolean value (true|false) but instead returned [_name]")); - } - public void testScriptConditionAccessCtx() throws Exception { ScriptCondition condition = new ScriptCondition(mockScript("ctx.trigger.scheduled_time.getMillis() < new Date().time"), scriptService); diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/history/HistoryActionConditionTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/history/HistoryActionConditionTests.java index 9093a6f86ae56..78fc9c290eddb 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/history/HistoryActionConditionTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/history/HistoryActionConditionTests.java @@ -24,6 +24,7 @@ import org.elasticsearch.xpack.watcher.condition.NeverCondition; import org.elasticsearch.xpack.watcher.condition.ScriptCondition; import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase; +import org.elasticsearch.xpack.watcher.test.WatcherMockScriptPlugin; import java.util.ArrayList; import java.util.Arrays; @@ -66,7 +67,7 @@ protected List> pluginTypes() { return types; } - public static class CustomScriptPlugin extends MockScriptPlugin { + public static class CustomScriptPlugin extends WatcherMockScriptPlugin { @Override protected Map, Object>> pluginScripts() { diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/input/transform/TransformInputTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/input/transform/TransformInputTests.java index 992cc98e471c7..5c0dd57cf2e6b 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/input/transform/TransformInputTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/input/transform/TransformInputTests.java @@ -13,8 +13,6 @@ import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.script.MockScriptEngine; import org.elasticsearch.script.Script; -import org.elasticsearch.script.ScriptContext; -import org.elasticsearch.script.ScriptEngine; import org.elasticsearch.script.ScriptService; import org.elasticsearch.script.ScriptType; import org.elasticsearch.test.ESTestCase; @@ -25,16 +23,14 @@ import org.elasticsearch.xpack.core.watcher.transform.TransformFactory; import org.elasticsearch.xpack.core.watcher.transform.TransformRegistry; import org.elasticsearch.xpack.core.watcher.watch.Payload; -import org.elasticsearch.xpack.watcher.Watcher; +import org.elasticsearch.xpack.watcher.test.WatcherMockScriptPlugin; import org.elasticsearch.xpack.watcher.test.WatcherTestUtils; import org.elasticsearch.xpack.watcher.transform.script.ExecutableScriptTransform; import org.elasticsearch.xpack.watcher.transform.script.ScriptTransform; import org.elasticsearch.xpack.watcher.transform.script.ScriptTransformFactory; -import org.elasticsearch.xpack.watcher.transform.script.WatcherTransformScript; import org.junit.Before; import java.util.Collections; -import java.util.HashMap; import java.util.Map; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; @@ -47,14 +43,7 @@ public class TransformInputTests extends ESTestCase { @Before public void setupScriptService() { - Map engines = new HashMap<>(); - engines.put(MockScriptEngine.NAME, - new MockScriptEngine(MockScriptEngine.NAME, Collections.singletonMap("1", s -> "2"), Collections.emptyMap())); - Map> contexts = new HashMap<>(); - contexts.put(Watcher.SCRIPT_TEMPLATE_CONTEXT.name, Watcher.SCRIPT_TEMPLATE_CONTEXT); - contexts.put(Watcher.SCRIPT_SEARCH_CONTEXT.name, Watcher.SCRIPT_SEARCH_CONTEXT); - contexts.put(WatcherTransformScript.CONTEXT.name, WatcherTransformScript.CONTEXT); - scriptService = new ScriptService(Settings.EMPTY, engines, contexts); + scriptService = WatcherMockScriptPlugin.newMockScriptService(Collections.singletonMap("1", s -> "2")); } public void testExecute() { diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/WatcherMockScriptPlugin.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/WatcherMockScriptPlugin.java new file mode 100644 index 0000000000000..afcd4b1a7c549 --- /dev/null +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/WatcherMockScriptPlugin.java @@ -0,0 +1,88 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch 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.elasticsearch.xpack.watcher.test; + +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.script.MockScriptEngine; +import org.elasticsearch.script.MockScriptPlugin; +import org.elasticsearch.script.ScriptContext; +import org.elasticsearch.script.ScriptEngine; +import org.elasticsearch.script.ScriptService; +import org.elasticsearch.xpack.watcher.Watcher; +import org.elasticsearch.xpack.watcher.condition.WatcherConditionScript; +import org.elasticsearch.xpack.watcher.transform.script.WatcherTransformScript; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * Provides a mock script engine with mock versions of watcher scripts. + */ +public abstract class WatcherMockScriptPlugin extends MockScriptPlugin { + public static final Map, MockScriptEngine.ContextCompiler> CONTEXT_COMPILERS; + static { + Map, MockScriptEngine.ContextCompiler> compilers = new HashMap<>(); + compilers.put(WatcherConditionScript.CONTEXT, (script, options) -> + (WatcherConditionScript.Factory) (params, watcherContext) -> + new WatcherConditionScript(params, watcherContext) { + @Override + public boolean execute() { + Map vars = new HashMap<>(); + vars.put("params", getParams()); + vars.put("ctx", getCtx()); + return (boolean) script.apply(vars); + } + }); + compilers.put(WatcherTransformScript.CONTEXT, (script, options) -> + (WatcherTransformScript.Factory) (params, watcherContext, payload) -> + new WatcherTransformScript(params, watcherContext, payload) { + @Override + public Object execute() { + Map vars = new HashMap<>(); + vars.put("params", getParams()); + vars.put("ctx", getCtx()); + return script.apply(vars); + } + }); + CONTEXT_COMPILERS = Collections.unmodifiableMap(compilers); + } + + public static final List> CONTEXTS = Collections.unmodifiableList(Arrays.asList( + WatcherConditionScript.CONTEXT, WatcherTransformScript.CONTEXT, Watcher.SCRIPT_TEMPLATE_CONTEXT, Watcher.SCRIPT_SEARCH_CONTEXT + )); + + @Override + protected Map, MockScriptEngine.ContextCompiler> pluginContextCompilers() { + return CONTEXT_COMPILERS; + } + + public static ScriptService newMockScriptService(Map, Object>> scripts) { + Map engines = new HashMap<>(); + engines.put(MockScriptEngine.NAME, + new MockScriptEngine(MockScriptEngine.NAME, scripts, CONTEXT_COMPILERS)); + Map> contexts = CONTEXTS.stream().collect(Collectors.toMap(o -> o.name, Function.identity())); + return new ScriptService(Settings.EMPTY, engines, contexts); + } +} diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/ExecutionVarsIntegrationTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/ExecutionVarsIntegrationTests.java index b3c96fed39d63..90b14233b8d27 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/ExecutionVarsIntegrationTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/ExecutionVarsIntegrationTests.java @@ -9,17 +9,13 @@ import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.protocol.xpack.watcher.PutWatchResponse; -import org.elasticsearch.script.MockScriptEngine; -import org.elasticsearch.script.MockScriptPlugin; -import org.elasticsearch.script.ScriptContext; import org.elasticsearch.xpack.core.watcher.client.WatcherClient; import org.elasticsearch.xpack.core.watcher.support.xcontent.ObjectPath; import org.elasticsearch.xpack.core.watcher.support.xcontent.XContentSource; import org.elasticsearch.xpack.core.watcher.transport.actions.execute.ExecuteWatchResponse; import org.elasticsearch.xpack.watcher.condition.ScriptCondition; -import org.elasticsearch.xpack.watcher.condition.WatcherConditionScript; import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase; -import org.elasticsearch.xpack.watcher.transform.script.WatcherTransformScript; +import org.elasticsearch.xpack.watcher.test.WatcherMockScriptPlugin; import org.hamcrest.Matcher; import java.util.HashMap; @@ -50,7 +46,7 @@ protected List> pluginTypes() { return types; } - public static class CustomScriptPlugin extends MockScriptPlugin { + public static class CustomScriptPlugin extends WatcherMockScriptPlugin { @Override @SuppressWarnings("unchecked") @@ -109,27 +105,6 @@ protected Map, Object>> pluginScripts() { return scripts; } - - protected Map, MockScriptEngine.ContextCompiler> pluginContextCompilers() { - HashMap, MockScriptEngine.ContextCompiler> compilers = new HashMap<>(); - compilers.put(WatcherConditionScript.CONTEXT, (script, options) -> - (WatcherConditionScript.Factory) (params, watcherContext) -> - new WatcherConditionScript(params, watcherContext) { - @Override - public boolean execute() { - return (boolean) script.apply(getParams()); - } - }); - compilers.put(WatcherTransformScript.CONTEXT, (script, options) -> - (WatcherTransformScript.Factory) (params, watcherContext, payload) -> - new WatcherTransformScript(params, watcherContext, payload) { - @Override - public Object execute() { - return script.apply(getParams()); - } - }); - return compilers; - } } public void testVars() throws Exception { diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/TransformIntegrationTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/TransformIntegrationTests.java index d629c54934fc1..044c3d3061ee0 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/TransformIntegrationTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/TransformIntegrationTests.java @@ -18,6 +18,7 @@ import org.elasticsearch.xpack.watcher.condition.InternalAlwaysCondition; import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateRequest; import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase; +import org.elasticsearch.xpack.watcher.test.WatcherMockScriptPlugin; import java.io.IOException; import java.io.UncheckedIOException; @@ -78,7 +79,7 @@ protected Path nodeConfigPath(int nodeOrdinal) { return config; } - public static class CustomScriptPlugin extends MockScriptPlugin { + public static class CustomScriptPlugin extends WatcherMockScriptPlugin { @Override protected Map, Object>> pluginScripts() { diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/script/ScriptTransformTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/script/ScriptTransformTests.java index ba5d225792b1d..752b753f028ff 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/script/ScriptTransformTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transform/script/ScriptTransformTests.java @@ -22,7 +22,6 @@ import org.elasticsearch.xpack.core.watcher.watch.Payload; import org.elasticsearch.xpack.core.watcher.watch.Watch; import org.elasticsearch.xpack.watcher.Watcher; -import org.elasticsearch.xpack.watcher.support.Variables; import java.util.Collections; import java.util.HashMap; @@ -59,13 +58,11 @@ public void testExecuteMapValue() throws Exception { Payload payload = new Payload.Simple("key", "value"); - Map model = Variables.createCtxParamsMap(ctx, payload); - Map transformed = singletonMap("key", "value"); WatcherTransformScript executable = mock(WatcherTransformScript.class); when(executable.execute()).thenReturn(transformed); - when(factory.newInstance(model, ctx, payload)).thenReturn(executable); + when(factory.newInstance(params, ctx, payload)).thenReturn(executable); Transform.Result result = transform.execute(ctx, payload); assertThat(result, notNullValue()); @@ -87,11 +84,9 @@ public void testExecuteMapValueFailure() throws Exception { Payload payload = new Payload.Simple("key", "value"); - Map model = Variables.createCtxParamsMap(ctx, payload); - WatcherTransformScript executable = mock(WatcherTransformScript.class); when(executable.execute()).thenThrow(new RuntimeException("_error")); - when(factory.newInstance(model, ctx, payload)).thenReturn(executable); + when(factory.newInstance(params, ctx, payload)).thenReturn(executable); Transform.Result result = transform.execute(ctx, payload); assertThat(result, notNullValue()); @@ -113,12 +108,10 @@ public void testExecuteNonMapValue() throws Exception { Payload payload = new Payload.Simple("key", "value"); - Map model = Variables.createCtxParamsMap(ctx, payload); - WatcherTransformScript executable = mock(WatcherTransformScript.class); Object value = randomFrom("value", 1, new String[] { "value" }, Collections.singletonList("value"), singleton("value")); when(executable.execute()).thenReturn(value); - when(factory.newInstance(model, ctx, payload)).thenReturn(executable); + when(factory.newInstance(params, ctx, payload)).thenReturn(executable); Transform.Result result = transform.execute(ctx, payload); assertThat(result, notNullValue()); From d6202eb63812eecec0ed960e5ee8f18021c2eae4 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Thu, 27 Sep 2018 18:23:13 -0700 Subject: [PATCH 11/12] fix checkstyle --- .../xpack/watcher/condition/ScriptConditionTests.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java index 4e8c83ecf91c7..fc6161cb9279c 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/condition/ScriptConditionTests.java @@ -102,7 +102,8 @@ public void testExecute() throws Exception { } public void testExecuteMergedParams() throws Exception { - Script script = new Script(ScriptType.INLINE, "mockscript", "ctx.payload.hits.total > params.threshold", singletonMap("threshold", 1)); + Script script = new Script(ScriptType.INLINE, "mockscript", + "ctx.payload.hits.total > params.threshold", singletonMap("threshold", 1)); ScriptCondition executable = new ScriptCondition(script, scriptService); SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 0, 500L, ShardSearchFailure.EMPTY_ARRAY, SearchResponse.Clusters.EMPTY); From f580545816f36e52040e40cc7877e99bc69f5854 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Thu, 27 Sep 2018 20:12:57 -0700 Subject: [PATCH 12/12] fix license header --- .../watcher/test/WatcherMockScriptPlugin.java | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/WatcherMockScriptPlugin.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/WatcherMockScriptPlugin.java index afcd4b1a7c549..2908dbaa6cc14 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/WatcherMockScriptPlugin.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/WatcherMockScriptPlugin.java @@ -1,22 +1,8 @@ /* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. */ - package org.elasticsearch.xpack.watcher.test; import org.elasticsearch.common.settings.Settings;