diff --git a/elasticsearch/qa/messy-test-watcher-with-groovy/build.gradle b/elasticsearch/qa/messy-test-watcher-with-groovy/build.gradle index 20b32521238..7ceedf70e28 100644 --- a/elasticsearch/qa/messy-test-watcher-with-groovy/build.gradle +++ b/elasticsearch/qa/messy-test-watcher-with-groovy/build.gradle @@ -9,6 +9,4 @@ apply plugin: 'elasticsearch.messy-test' dependencies { testCompile project(path: ':x-plugins:elasticsearch:x-pack', configuration: 'testArtifacts') testCompile project(path: ':modules:lang-groovy', configuration: 'runtime') - // some tests depend on both groovy and mustache! this is really bad! - testCompile project(path: ':modules:lang-mustache', configuration: 'runtime') } diff --git a/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/ExecutionVarsIntegrationTests.java b/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/ExecutionVarsIntegrationTests.java index 6ba797fa02e..91827345543 100644 --- a/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/ExecutionVarsIntegrationTests.java +++ b/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/ExecutionVarsIntegrationTests.java @@ -27,6 +27,7 @@ import static org.elasticsearch.watcher.input.InputBuilders.simpleInput; import static org.elasticsearch.watcher.transform.TransformBuilders.scriptTransform; import static org.elasticsearch.watcher.trigger.TriggerBuilders.schedule; import static org.elasticsearch.watcher.trigger.schedule.Schedules.cron; +import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; @@ -57,12 +58,12 @@ public class ExecutionVarsIntegrationTests extends AbstractWatcherIntegrationTes .transform(scriptTransform("ctx.vars.watch_transform_value = ctx.vars.condition_value + 5; return ctx.payload;")) .addAction( "a1", - scriptTransform("ctx.vars.a1_transform_value = ctx.vars.watch_transform_value + 10; return ctx.payload;"), - loggingAction("condition_value={{ctx.vars.condition_value}}, watch_transform_value={{ctx.vars.watch_transform_value}}, a1_transform_value={{ctx.vars.a1_transform_value}}")) + scriptTransform("ctx.vars.a1_transform_value = ctx.vars.watch_transform_value + 10; ctx.payload.a1_transformed_value = ctx.vars.a1_transform_value; return ctx.payload;"), + loggingAction("_text")) .addAction( "a2", - scriptTransform("ctx.vars.a2_transform_value = ctx.vars.watch_transform_value + 20; return ctx.payload;"), - loggingAction("condition_value={{ctx.vars.condition_value}}, watch_transform_value={{ctx.vars.watch_transform_value}}, a2_transform_value={{ctx.vars.a2_transform_value}}"))) + scriptTransform("ctx.vars.a2_transform_value = ctx.vars.watch_transform_value + 20; ctx.payload.a2_transformed_value = ctx.vars.a2_transform_value; return ctx.payload;"), + loggingAction("_text"))) .get(); assertThat(putWatchResponse.isCreated(), is(true)); @@ -99,12 +100,12 @@ public class ExecutionVarsIntegrationTests extends AbstractWatcherIntegrationTes case "a1": assertValue(action, "status", is("success")); assertValue(action, "transform.status", is("success")); - assertValue(action, "logging.logged_text", is("condition_value=10, watch_transform_value=15, a1_transform_value=25")); + assertValue(action, "transform.payload.a1_transformed_value", equalTo(25)); break; case "a2": assertValue(action, "status", is("success")); assertValue(action, "transform.status", is("success")); - assertValue(action, "logging.logged_text", is("condition_value=10, watch_transform_value=15, a2_transform_value=35")); + assertValue(action, "transform.payload.a2_transformed_value", equalTo(35)); break; default: fail("there should not be an action result for action with an id other than a1 or a2"); @@ -122,12 +123,12 @@ public class ExecutionVarsIntegrationTests extends AbstractWatcherIntegrationTes .transform(scriptTransform("ctx.vars.watch_transform_value = ctx.vars.condition_value + 5; return ctx.payload;")) .addAction( "a1", - scriptTransform("ctx.vars.a1_transform_value = ctx.vars.watch_transform_value + 10; return ctx.payload;"), - loggingAction("condition_value={{ctx.vars.condition_value}}, watch_transform_value={{ctx.vars.watch_transform_value}}, a1_transform_value={{ctx.vars.a1_transform_value}}")) + scriptTransform("ctx.vars.a1_transform_value = ctx.vars.watch_transform_value + 10; ctx.payload.a1_transformed_value = ctx.vars.a1_transform_value; return ctx.payload;"), + loggingAction("_text")) .addAction( "a2", - scriptTransform("ctx.vars.a2_transform_value = ctx.vars.watch_transform_value + 20; return ctx.payload;"), - loggingAction("condition_value={{ctx.vars.condition_value}}, watch_transform_value={{ctx.vars.watch_transform_value}}, a2_transform_value={{ctx.vars.a2_transform_value}}"))) + scriptTransform("ctx.vars.a2_transform_value = ctx.vars.watch_transform_value + 20; ctx.payload.a2_transformed_value = ctx.vars.a2_transform_value; return ctx.payload;"), + loggingAction("_text"))) .get(); assertThat(putWatchResponse.isCreated(), is(true)); @@ -161,12 +162,12 @@ public class ExecutionVarsIntegrationTests extends AbstractWatcherIntegrationTes case "a1": assertValue(action, "status", is("success")); assertValue(action, "transform.status", is("success")); - assertValue(action, "logging.logged_text", is("condition_value=10, watch_transform_value=15, a1_transform_value=25")); + assertValue(action, "transform.payload.a1_transformed_value", equalTo(25)); break; case "a2": assertValue(action, "status", is("success")); assertValue(action, "transform.status", is("success")); - assertValue(action, "logging.logged_text", is("condition_value=10, watch_transform_value=15, a2_transform_value=35")); + assertValue(action, "transform.payload.a2_transformed_value", equalTo(35)); break; default: fail("there should not be an action result for action with an id other than a1 or a2"); diff --git a/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/IndexActionIntegrationTests.java b/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/IndexActionIntegrationTests.java index 4eef0727324..719ac19ff0e 100644 --- a/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/IndexActionIntegrationTests.java +++ b/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/IndexActionIntegrationTests.java @@ -10,7 +10,6 @@ import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchType; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.script.groovy.GroovyPlugin; -import org.elasticsearch.script.mustache.MustachePlugin; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval; import org.elasticsearch.search.sort.SortOrder; @@ -49,7 +48,6 @@ public class IndexActionIntegrationTests extends AbstractWatcherIntegrationTestC protected List> pluginTypes() { List> types = super.pluginTypes(); types.add(GroovyPlugin.class); - types.add(MustachePlugin.class); return types; } diff --git a/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/MessyTestUtils.java b/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/MessyTestUtils.java index f1763f188c9..4715b1ce3f8 100644 --- a/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/MessyTestUtils.java +++ b/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/MessyTestUtils.java @@ -18,7 +18,6 @@ import org.elasticsearch.script.groovy.GroovyScriptEngineService; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy; -import org.elasticsearch.watcher.support.text.xmustache.XMustacheScriptEngineService; import org.junit.Ignore; import java.util.Arrays; @@ -34,15 +33,12 @@ public final class MessyTestUtils { .put("script.indexed", "true") .put("path.home", LuceneTestCase.createTempDir()) .build(); - XMustacheScriptEngineService mustacheScriptEngineService = new XMustacheScriptEngineService(settings); GroovyScriptEngineService groovyScriptEngineService = new GroovyScriptEngineService(settings); Set engineServiceSet = new HashSet<>(); - engineServiceSet.add(mustacheScriptEngineService); engineServiceSet.add(groovyScriptEngineService); ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry( Arrays.asList( - new ScriptEngineRegistry.ScriptEngineRegistration(GroovyScriptEngineService.class, GroovyScriptEngineService.TYPES), - new ScriptEngineRegistry.ScriptEngineRegistration(XMustacheScriptEngineService.class, XMustacheScriptEngineService.TYPES) + new ScriptEngineRegistry.ScriptEngineRegistration(GroovyScriptEngineService.class, GroovyScriptEngineService.TYPES) ) ); ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Arrays.asList(ScriptServiceProxy.INSTANCE)); diff --git a/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/TransformIntegrationTests.java b/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/TransformIntegrationTests.java index 761674c932f..0dbdca112ef 100644 --- a/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/TransformIntegrationTests.java +++ b/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/TransformIntegrationTests.java @@ -12,7 +12,6 @@ import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.script.groovy.GroovyPlugin; -import org.elasticsearch.script.mustache.MustachePlugin; import org.elasticsearch.watcher.support.Script; import org.elasticsearch.watcher.test.AbstractWatcherIntegrationTestCase; import org.elasticsearch.watcher.test.WatcherTestUtils; @@ -52,7 +51,6 @@ public class TransformIntegrationTests extends AbstractWatcherIntegrationTestCas protected List> pluginTypes() { List> types = super.pluginTypes(); types.add(GroovyPlugin.class); - types.add(MustachePlugin.class); return types; } diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/EmailActionIntegrationTests.java b/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/EmailActionIntegrationTests.java deleted file mode 100644 index 5acf8919b4f..00000000000 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/EmailActionIntegrationTests.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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.messy.tests; - -import org.elasticsearch.action.search.SearchRequest; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.script.mustache.MustachePlugin; -import org.elasticsearch.test.ESIntegTestCase; -import org.elasticsearch.test.junit.annotations.TestLogging; -import org.elasticsearch.watcher.actions.email.service.EmailTemplate; -import org.elasticsearch.watcher.actions.email.service.support.EmailServer; -import org.elasticsearch.watcher.client.WatcherClient; -import org.elasticsearch.watcher.condition.compare.CompareCondition; -import org.elasticsearch.watcher.test.AbstractWatcherIntegrationTestCase; -import org.elasticsearch.watcher.trigger.schedule.IntervalSchedule; -import org.junit.After; - -import javax.mail.internet.MimeMessage; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import static org.elasticsearch.index.query.QueryBuilders.termQuery; -import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource; -import static org.elasticsearch.test.ESIntegTestCase.Scope.SUITE; -import static org.elasticsearch.watcher.actions.ActionBuilders.emailAction; -import static org.elasticsearch.watcher.client.WatchSourceBuilders.watchBuilder; -import static org.elasticsearch.watcher.condition.ConditionBuilders.compareCondition; -import static org.elasticsearch.watcher.input.InputBuilders.searchInput; -import static org.elasticsearch.watcher.test.WatcherTestUtils.newInputSearchRequest; -import static org.elasticsearch.watcher.trigger.TriggerBuilders.schedule; -import static org.elasticsearch.watcher.trigger.schedule.Schedules.interval; -import static org.hamcrest.Matchers.equalTo; - -@TestLogging("subethamail:TRACE,watcher:TRACE") -@ESIntegTestCase.ClusterScope(scope = SUITE, numClientNodes = 0, transportClientRatio = 0, randomDynamicTemplates = false, numDataNodes = 1) -public class EmailActionIntegrationTests extends AbstractWatcherIntegrationTestCase { - static final String USERNAME = "_user"; - static final String PASSWORD = "_passwd"; - - private EmailServer server; - - @After - public void cleanup() throws Exception { - server.stop(); - } - - @Override - protected List> pluginTypes() { - List> types = new ArrayList<>(); - types.addAll(super.pluginTypes()); - types.add(MustachePlugin.class); - return types; - } - - @Override - protected Settings nodeSettings(int nodeOrdinal) { - if(server == null) { - //Need to construct the Email Server here as this happens before init() - server = EmailServer.localhost("2500-2600", USERNAME, PASSWORD, logger); - } - return Settings.builder() - .put(super.nodeSettings(nodeOrdinal)) - .put("watcher.actions.email.service.account.test.smtp.auth", true) - .put("watcher.actions.email.service.account.test.smtp.user", USERNAME) - .put("watcher.actions.email.service.account.test.smtp.password", PASSWORD) - .put("watcher.actions.email.service.account.test.smtp.port", server.port()) - .put("watcher.actions.email.service.account.test.smtp.host", "localhost") - .build(); - } - - public void testArrayAccess() throws Exception { - final CountDownLatch latch = new CountDownLatch(1); - server.addListener(new EmailServer.Listener() { - @Override - public void on(MimeMessage message) throws Exception { - assertThat(message.getSubject(), equalTo("value")); - latch.countDown(); - } - }); - - WatcherClient watcherClient = watcherClient(); - createIndex("idx"); - // Have a sample document in the index, the watch is going to evaluate - client().prepareIndex("idx", "type").setSource("field", "value").get(); - refresh(); - SearchRequest searchRequest = newInputSearchRequest("idx").source(searchSource().query(termQuery("field", "value"))); - watcherClient.preparePutWatch("_id") - .setSource(watchBuilder() - .trigger(schedule(interval(5, IntervalSchedule.Interval.Unit.SECONDS))) - .input(searchInput(searchRequest)) - .condition(compareCondition("ctx.payload.hits.total", CompareCondition.Op.GT, 0L)) - .addAction("_email", emailAction(EmailTemplate.builder().from("_from").to("_to") - .subject("{{ctx.payload.hits.hits.0._source.field}}")).setAuthentication(USERNAME, PASSWORD.toCharArray()))) - .get(); - - if (timeWarped()) { - timeWarp().scheduler().trigger("_id"); - refresh(); - } - - assertWatchWithMinimumPerformedActionsCount("_id", 1); - - if (!latch.await(5, TimeUnit.SECONDS)) { - fail("waited too long for email to be received"); - } - } -} diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/package-info.java b/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/package-info.java index ef824b701fc..7fbaf25da1a 100644 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/package-info.java +++ b/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/package-info.java @@ -21,12 +21,8 @@ */ // renames that took place: -// renamed: x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/integration/BasicWatcherTests.java -> qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/BasicWatcherTests.java -// renamed: x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/EmailActionIntegrationTests.java -> qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/EmailActionIntegrationTests.java -// renamed: x-pack/watcher/src/test/java/org/elasticsearch/watcher/history/HistoryTemplateSearchInputMappingsTests.java -> qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/HistoryTemplateSearchInputMappingsTests.java // renamed: x-pack/watcher/src/test/java/org/elasticsearch/watcher/input/search/SearchInputTests.java -> qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/SearchInputTests.java // renamed: x-pack/watcher/src/test/java/org/elasticsearch/watcher/transform/search/SearchTransformTests.java -> qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/SearchTransformTests.java // renamed: x-pack/shield/src/test/java/org/elasticsearch/integration/ShieldCachePermissionTests.java -> qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/ShieldCachePermissionTests.java -// renamed: x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/TimeThrottleIntegrationTests.java -> qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/TimeThrottleIntegrationTests.java package org.elasticsearch.messy.tests; diff --git a/elasticsearch/qa/smoke-test-watcher-with-mustache/build.gradle b/elasticsearch/qa/smoke-test-watcher-with-mustache/build.gradle new file mode 100644 index 00000000000..1dd218346b7 --- /dev/null +++ b/elasticsearch/qa/smoke-test-watcher-with-mustache/build.gradle @@ -0,0 +1,15 @@ +apply plugin: 'elasticsearch.rest-test' + +dependencies { + testCompile project(path: ':x-plugins:elasticsearch:x-pack', configuration: 'runtime') + testCompile project(path: ':modules:lang-mustache', configuration: 'runtime') +} + +integTest { + cluster { + plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack') + systemProperty 'es.shield.enabled', 'false' + systemProperty 'es.marvel.enabled', 'false' + systemProperty 'es.http.port', '9400' + } +} diff --git a/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherRestTestCase.java b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherRestTestCase.java new file mode 100644 index 00000000000..51669a9d30c --- /dev/null +++ b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherRestTestCase.java @@ -0,0 +1,52 @@ +/* + * 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.smoketest; + +import com.carrotsearch.randomizedtesting.annotations.Name; +import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.BasicHttpClientConnectionManager; +import org.elasticsearch.test.rest.ESRestTestCase; +import org.elasticsearch.test.rest.RestTestCandidate; +import org.elasticsearch.test.rest.parser.RestTestParseException; +import org.junit.After; +import org.junit.Before; + +import java.io.IOException; +import java.net.URI; +import java.net.URL; + +public abstract class WatcherRestTestCase extends ESRestTestCase { + + public WatcherRestTestCase(@Name("yaml") RestTestCandidate testCandidate) { + super(testCandidate); + } + + @ParametersFactory + public static Iterable parameters() throws IOException, RestTestParseException { + return ESRestTestCase.createParameters(0, 1); + } + + @Before + public void startWatcher() throws Exception { + try(CloseableHttpClient client = HttpClients.createMinimal(new BasicHttpClientConnectionManager())) { + URL url = getClusterUrls()[0]; + HttpPut request = new HttpPut(new URI("http", null, url.getHost(), url.getPort(), "/_watcher/_start", null, null)); + client.execute(request); + } + } + + @After + public void stopWatcher() throws Exception { + try(CloseableHttpClient client = HttpClients.createMinimal(new BasicHttpClientConnectionManager())) { + URL url = getClusterUrls()[0]; + HttpPut request = new HttpPut(new URI("http", null, url.getHost(), url.getPort(), "/_watcher/_stop", null, null)); + client.execute(request); + } + } +} diff --git a/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherTemplateIT.java b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherTemplateIT.java new file mode 100644 index 00000000000..698f834b49a --- /dev/null +++ b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherTemplateIT.java @@ -0,0 +1,185 @@ +/* + * 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.smoketest; + +import com.fasterxml.jackson.core.io.JsonStringEncoder; +import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.env.Environment; +import org.elasticsearch.script.ScriptContextRegistry; +import org.elasticsearch.script.ScriptEngineRegistry; +import org.elasticsearch.script.ScriptEngineService; +import org.elasticsearch.script.ScriptService; +import org.elasticsearch.script.ScriptSettings; +import org.elasticsearch.script.mustache.MustacheScriptEngineService; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.watcher.ResourceWatcherService; +import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy; +import org.elasticsearch.watcher.support.text.DefaultTextTemplateEngine; +import org.elasticsearch.watcher.support.text.TextTemplate; +import org.elasticsearch.watcher.support.text.TextTemplateEngine; +import org.junit.Before; +import org.mockito.Mockito; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.Locale; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; + +public class WatcherTemplateIT extends ESTestCase { + + private TextTemplateEngine engine; + + @Before + public void init() throws Exception { + Settings setting = Settings.builder().put(ScriptService.SCRIPT_AUTO_RELOAD_ENABLED_SETTING, true).build(); + Environment environment = Mockito.mock(Environment.class); + Set engines = Collections.singleton(new MustacheScriptEngineService(setting)); + ResourceWatcherService resourceWatcherService = Mockito.mock(ResourceWatcherService.class); + ScriptContextRegistry registry = new ScriptContextRegistry(Collections.singletonList(ScriptServiceProxy.INSTANCE)); + + ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry( + Arrays.asList( + new ScriptEngineRegistry.ScriptEngineRegistration(MustacheScriptEngineService.class, MustacheScriptEngineService.TYPES) + ) + ); + ScriptSettings scriptSettings = new ScriptSettings(scriptEngineRegistry, registry); + ScriptService scriptService = new ScriptService(setting, environment, engines, resourceWatcherService, scriptEngineRegistry, registry, scriptSettings); + engine = new DefaultTextTemplateEngine(Settings.EMPTY, ScriptServiceProxy.of(scriptService)); + } + + public void testEscaping() throws Exception { + XContentType contentType = randomFrom(XContentType.values()); + if (rarely()) { + contentType = null; + } + Character[] specialChars = new Character[]{'\f', '\n', '\r', '"', '\\', (char) 11, '\t', '\b' }; + int iters = scaledRandomIntBetween(100, 1000); + for (int i = 0; i < iters; i++) { + int rounds = scaledRandomIntBetween(1, 20); + StringWriter escaped = new StringWriter(); //This will be escaped as it is constructed + StringWriter unescaped = new StringWriter(); //This will be escaped at the end + + for (int j = 0; j < rounds; j++) { + String s = getChars(); + unescaped.write(s); + if (contentType == XContentType.JSON) { + escaped.write(JsonStringEncoder.getInstance().quoteAsString(s)); + } else { + escaped.write(s); + } + + char c = randomFrom(specialChars); + unescaped.append(c); + + if (contentType == XContentType.JSON) { + escaped.write(JsonStringEncoder.getInstance().quoteAsString("" + c)); + } else { + escaped.append(c); + } + } + + if (contentType == XContentType.JSON) { + assertThat(escaped.toString(), equalTo(new String(JsonStringEncoder.getInstance().quoteAsString(unescaped.toString())))); + } + else { + assertThat(escaped.toString(), equalTo(unescaped.toString())); + } + + String template = prepareTemplate("{{data}}", contentType); + + Map dataMap = new HashMap<>(); + dataMap.put("data", unescaped.toString()); + String renderedTemplate = engine.render(new TextTemplate(template), dataMap); + assertThat(renderedTemplate, notNullValue()); + + if (contentType == XContentType.JSON) { + if (!escaped.toString().equals(renderedTemplate)) { + String escapedString = escaped.toString(); + for (int l = 0; l < renderedTemplate.length() && l < escapedString.length(); ++l) { + if (renderedTemplate.charAt(l) != escapedString.charAt(l)) { + logger.error("at [{}] expected [{}] but got [{}]", l, renderedTemplate.charAt(l), escapedString.charAt(l)); + } + } + } + assertThat(escaped.toString(), equalTo(renderedTemplate)); + } else { + assertThat(unescaped.toString(), equalTo(renderedTemplate)); + } + } + } + + public void testSimpleParameterReplace() { + { + String template = "__json__::GET _search {\"query\": " + "{\"boosting\": {" + "\"positive\": {\"match\": {\"body\": \"gift\"}}," + + "\"negative\": {\"term\": {\"body\": {\"value\": \"solr\"}" + "}}, \"negative_boost\": {{boost_val}} } }}"; + Map vars = new HashMap<>(); + vars.put("boost_val", "0.3"); + String result = engine.render(new TextTemplate(template), vars); + assertEquals("GET _search {\"query\": {\"boosting\": {\"positive\": {\"match\": {\"body\": \"gift\"}}," + + "\"negative\": {\"term\": {\"body\": {\"value\": \"solr\"}}}, \"negative_boost\": 0.3 } }}", + result); + } + { + String template = "__json__::GET _search {\"query\": " + "{\"boosting\": {" + "\"positive\": {\"match\": {\"body\": \"gift\"}}," + + "\"negative\": {\"term\": {\"body\": {\"value\": \"{{body_val}}\"}" + "}}, \"negative_boost\": {{boost_val}} } }}"; + Map vars = new HashMap<>(); + vars.put("boost_val", "0.3"); + vars.put("body_val", "\"quick brown\""); + String result = engine.render(new TextTemplate(template), vars); + assertEquals("GET _search {\"query\": {\"boosting\": {\"positive\": {\"match\": {\"body\": \"gift\"}}," + + "\"negative\": {\"term\": {\"body\": {\"value\": \"\\\"quick brown\\\"\"}}}, \"negative_boost\": 0.3 } }}", + result); + } + } + + public void testInvalidPrefixes() throws Exception { + String[] specialStrings = new String[]{"\f", "\n", "\r", "\"", "\\", "\t", "\b", "__::", "__" }; + String prefix = randomFrom("", "__", "____::", "___::", "____", "::", "++json__::", "__json__", "+_json__::", "__json__:"); + String template = prefix + " {{test_var1}} {{test_var2}}"; + Map vars = new HashMap<>(); + Writer var1Writer = new StringWriter(); + Writer var2Writer = new StringWriter(); + + for(int i = 0; i < scaledRandomIntBetween(10,1000); ++i) { + var1Writer.write(randomRealisticUnicodeOfCodepointLengthBetween(0, 10)); + var2Writer.write(randomRealisticUnicodeOfCodepointLengthBetween(0, 10)); + var1Writer.append(randomFrom(specialStrings)); + var2Writer.append(randomFrom(specialStrings)); + } + + vars.put("test_var1", var1Writer.toString()); + vars.put("test_var2", var2Writer.toString()); + String s1 = engine.render(new TextTemplate(template), vars); + String s2 = prefix + " " + var1Writer.toString() + " " + var2Writer.toString(); + assertThat(s1, equalTo(s2)); + } + + static String getChars() throws IOException { + return randomRealisticUnicodeOfCodepointLengthBetween(0, 10); + } + + static String prepareTemplate(String template, @Nullable XContentType contentType) { + if (contentType == null) { + return template; + } + return new StringBuilder("__") + .append(contentType.shortName().toLowerCase(Locale.ROOT)) + .append("__::") + .append(template) + .toString(); + } + +} diff --git a/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherWithMustacheIT.java b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherWithMustacheIT.java new file mode 100644 index 00000000000..4865aa483ad --- /dev/null +++ b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherWithMustacheIT.java @@ -0,0 +1,28 @@ +/* + * 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.smoketest; + +import com.carrotsearch.randomizedtesting.annotations.Name; +import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; +import org.elasticsearch.test.rest.ESRestTestCase; +import org.elasticsearch.test.rest.RestTestCandidate; +import org.elasticsearch.test.rest.parser.RestTestParseException; + +import java.io.IOException; + +/** Runs rest tests against external cluster */ +public class WatcherWithMustacheIT extends WatcherRestTestCase { + + public WatcherWithMustacheIT(@Name("yaml") RestTestCandidate testCandidate) { + super(testCandidate); + } + + @ParametersFactory + public static Iterable parameters() throws IOException, RestTestParseException { + return ESRestTestCase.createParameters(0, 1); + } + +} diff --git a/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/resources/rest-api-spec/test/watcher_mustache/10_webhook.yaml b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/resources/rest-api-spec/test/watcher_mustache/10_webhook.yaml new file mode 100644 index 00000000000..38363c35f71 --- /dev/null +++ b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/resources/rest-api-spec/test/watcher_mustache/10_webhook.yaml @@ -0,0 +1,67 @@ +--- +"Test webhook action with mustache integration": + - do: + cluster.health: + wait_for_status: yellow + + + - do: {watcher.stats:{}} + - match: { "watcher_state": "started" } + - match: { "watch_count": 0 } + + - do: + watcher.put_watch: + id: "test_watch" + body: > + { + "trigger": { + "schedule": { + "interval": "1s" + } + }, + "input": { + "simple" : { + "key" : "value" + } + }, + "condition": { + "always" : {} + }, + "actions": { + "output": { + "webhook" : { + "method" : "PUT", + "host" : "localhost", + "port" : 9400, + "path": "/my_index/my_type/{{ctx.watch_id}}", + "body" : { + "inline": { + "watch_id" : "{{ctx.watch_id}}" + }, + "params": {} + } + } + } + } + } + - match: { _id: "test_watch" } + - match: { created: true } + + - do: {watcher.stats:{}} + - match: { "watch_count": 1 } + + # Simulate a Thread.sleep() + - do: + catch: request_timeout + cluster.health: + wait_for_nodes: 99 + timeout: 10s + - match: { "timed_out": true } + + - do: + get: + index: my_index + type: my_type + id: test_watch + + - match: { _source: { watch_id: "test_watch" } } diff --git a/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/resources/rest-api-spec/test/watcher_mustache/20_array_access.yaml b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/resources/rest-api-spec/test/watcher_mustache/20_array_access.yaml new file mode 100644 index 00000000000..d1a346e24b9 --- /dev/null +++ b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/resources/rest-api-spec/test/watcher_mustache/20_array_access.yaml @@ -0,0 +1,62 @@ +--- +"Test array access": + - do: + cluster.health: + wait_for_status: yellow + + + - do: {watcher.stats:{}} + - match: { "watcher_state": "started" } + - match: { "watch_count": 0 } + + - do: + watcher.put_watch: + id: "test_watch" + body: > + { + "trigger": { + "schedule": { + "interval": "1s" + } + }, + "input": { + "simple" : { + "objects" : [ + { + "field": "value1" + }, + { + "field": "value2" + } + ] + } + }, + "condition": { + "always" : {} + }, + "actions": { + "output": { + "logging" : { + "text" : "{{ctx.payload.objects.0.field}} {{ctx.payload.objects.1.field}}" + } + } + } + } + - match: { _id: "test_watch" } + - match: { created: true } + + - do: {watcher.stats:{}} + - match: { "watch_count": 1 } + + # Simulate a Thread.sleep() + - do: + catch: request_timeout + cluster.health: + wait_for_nodes: 99 + timeout: 10s + - match: { "timed_out": true } + + - do: + search: + index: .watch_history-* + - match: { hits.hits.0._source.result.actions.0.logging.logged_text: "value1 value2" } diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/WatcherPlugin.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/WatcherPlugin.java index 91897d68520..da5ad267f7d 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/WatcherPlugin.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/WatcherPlugin.java @@ -59,7 +59,6 @@ import org.elasticsearch.watcher.support.init.InitializingService; import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy; import org.elasticsearch.watcher.support.secret.SecretModule; import org.elasticsearch.watcher.support.text.TextTemplateModule; -import org.elasticsearch.watcher.support.text.xmustache.XMustacheScriptEngineService; import org.elasticsearch.watcher.support.validation.WatcherSettingsValidation; import org.elasticsearch.watcher.transform.TransformModule; import org.elasticsearch.watcher.transport.actions.ack.AckWatchAction; @@ -182,9 +181,6 @@ public class WatcherPlugin extends Plugin { public void onModule(ScriptModule module) { module.registerScriptContext(ScriptServiceProxy.INSTANCE); - if (enabled && !transportClient) { - module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(XMustacheScriptEngineService.class, XMustacheScriptEngineService.TYPES)); - } } public void onModule(SettingsModule module) { diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/init/proxy/ScriptServiceProxy.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/init/proxy/ScriptServiceProxy.java index b874824e11e..229377cfec4 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/init/proxy/ScriptServiceProxy.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/init/proxy/ScriptServiceProxy.java @@ -45,12 +45,12 @@ public class ScriptServiceProxy implements InitializingService.Initializable { public CompiledScript compile(Script script) { return securityContext.executeAs(XPackUser.INSTANCE, () -> - compile(new org.elasticsearch.script.Script(script.script(), script.type(), script.lang(), script.params()))); + compile(new org.elasticsearch.script.Script(script.script(), script.type(), script.lang(), script.params()), Collections.emptyMap())); } - public CompiledScript compile(org.elasticsearch.script.Script script) { + public CompiledScript compile(org.elasticsearch.script.Script script, Map compileParams) { return securityContext.executeAs(XPackUser.INSTANCE, () -> - service.compile(script, WatcherScriptContext.CTX, Collections.emptyMap())); + service.compile(script, WatcherScriptContext.CTX, compileParams)); } public ExecutableScript executable(CompiledScript compiledScript, Map vars) { diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/DefaultTextTemplateEngine.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/DefaultTextTemplateEngine.java new file mode 100644 index 00000000000..697d24c68da --- /dev/null +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/DefaultTextTemplateEngine.java @@ -0,0 +1,88 @@ +/* + * 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.watcher.support.text; + +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.component.AbstractComponent; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.script.CompiledScript; +import org.elasticsearch.script.ExecutableScript; +import org.elasticsearch.script.Template; +import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class DefaultTextTemplateEngine extends AbstractComponent implements TextTemplateEngine { + + private final ScriptServiceProxy service; + + @Inject + public DefaultTextTemplateEngine(Settings settings, ScriptServiceProxy service) { + super(settings); + this.service = service; + } + + @Override + public String render(TextTemplate template, Map model) { + XContentType contentType = detectContentType(template); + Map compileParams = compileParams(contentType); + template = trimContentType(template); + + CompiledScript compiledScript = service.compile(convert(template, model), compileParams); + ExecutableScript executable = service.executable(compiledScript, model); + Object result = executable.run(); + if (result instanceof BytesReference) { + return ((BytesReference) result).toUtf8(); + } + return result.toString(); + } + + private TextTemplate trimContentType(TextTemplate textTemplate) { + String template = textTemplate.getTemplate(); + if (!template.startsWith("__")){ + return textTemplate; //Doesn't even start with __ so can't have a content type + } + int index = template.indexOf("__::", 3); //There must be a __= 0 && index < 12) { //Assume that the content type name is less than 10 characters long otherwise we may falsely detect strings that start with '__ and have '__::' somewhere in the content + if (template.length() == 6) { + template = ""; + } else { + template = template.substring(index + 4); + } + } + return new TextTemplate(template, textTemplate.getContentType(), textTemplate.getType(), textTemplate.getParams()); + } + + private XContentType detectContentType(TextTemplate textTemplate) { + String template = textTemplate.getTemplate(); + if (template.startsWith("__")) { + int endOfContentName = template.indexOf("__::", 3); //There must be a __ model) { + Map mergedModel = new HashMap<>(); + mergedModel.putAll(textTemplate.getParams()); + mergedModel.putAll(model); + return new Template(textTemplate.getTemplate(), textTemplate.getType(), "mustache", textTemplate.getContentType(), mergedModel); + } + + private Map compileParams(XContentType contentType) { + if (contentType == XContentType.JSON) { + return Collections.singletonMap("content_type", "application/json"); + } else { + return Collections.singletonMap("content_type", "text/plain"); + } + } +} diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/TextTemplate.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/TextTemplate.java index 5a5e1b6653e..c4b3199a695 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/TextTemplate.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/TextTemplate.java @@ -31,11 +31,11 @@ public class TextTemplate implements ToXContent { private final @Nullable ScriptType type; private final @Nullable Map params; - TextTemplate(String template) { + public TextTemplate(String template) { this(template, null, null, null); } - TextTemplate(String template, @Nullable XContentType contentType, @Nullable ScriptType type, @Nullable Map params) { + public TextTemplate(String template, @Nullable XContentType contentType, @Nullable ScriptType type, @Nullable Map params) { this.template = template; this.contentType = contentType; this.type = type; diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/TextTemplateModule.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/TextTemplateModule.java index 293eef7997e..45d4336c4aa 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/TextTemplateModule.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/TextTemplateModule.java @@ -6,7 +6,6 @@ package org.elasticsearch.watcher.support.text; import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.watcher.support.text.xmustache.XMustacheTextTemplateEngine; /** * @@ -15,7 +14,7 @@ public class TextTemplateModule extends AbstractModule { @Override protected void configure() { - bind(XMustacheTextTemplateEngine.class).asEagerSingleton(); - bind(TextTemplateEngine.class).to(XMustacheTextTemplateEngine.class); + bind(DefaultTextTemplateEngine.class).asEagerSingleton(); + bind(TextTemplateEngine.class).to(DefaultTextTemplateEngine.class); } } diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/xmustache/XMustacheFactory.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/xmustache/XMustacheFactory.java deleted file mode 100644 index cd4401902fd..00000000000 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/xmustache/XMustacheFactory.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * 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.watcher.support.text.xmustache; - -import com.fasterxml.jackson.core.io.JsonStringEncoder; -import com.github.mustachejava.DefaultMustacheFactory; -import com.github.mustachejava.MustacheException; -import com.github.mustachejava.reflect.ReflectionObjectHandler; -import org.elasticsearch.common.util.iterable.Iterables; -import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.watcher.support.ArrayObjectIterator; - -import java.io.IOException; -import java.io.Writer; -import java.lang.reflect.Array; -import java.util.AbstractMap; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -/** - * An extension to elasticsearch's {@code JsonEscapingMustacheFactory} that on top of applying json - * escapes it also enables support for navigating arrays using `array.X` notation (where `X` is the index - * of the element in the array). - */ -public class XMustacheFactory extends DefaultMustacheFactory { - - final XContentType contentType; - - public XMustacheFactory(XContentType contentType) { - this.contentType = contentType; - setObjectHandler(new ReflectionObjectHandler() { - @Override - public Object coerce(Object object) { - if (object != null) { - if (object.getClass().isArray()) { - return new ArrayMap(object); - } else if (object instanceof Collection) { - return new CollectionMap((Collection) object); - } - } - return super.coerce(object); - } - }); - } - - @Override - public void encode(String value, Writer writer) { - try { - if (contentType == XContentType.JSON) { - writer.write(JsonStringEncoder.getInstance().quoteAsString(value)); - } else { - writer.write(value); - } - } catch (IOException e) { - throw new MustacheException("Failed to encode value: " + value); - } - } - - static class ArrayMap extends AbstractMap implements Iterable { - - private final Object array; - - public ArrayMap(Object array) { - this.array = array; - } - - @Override - public Object get(Object key) { - if (key instanceof Number) { - return Array.get(array, ((Number) key).intValue()); - } - try { - int index = Integer.parseInt(key.toString()); - return Array.get(array, index); - } catch (NumberFormatException nfe) { - // if it's not a number it is as if the key doesn't exist - return null; - } - } - - @Override - public boolean containsKey(Object key) { - return get(key) != null; - } - - @Override - public Set> entrySet() { - int length = Array.getLength(array); - Map map = new HashMap<>(length); - for (int i = 0; i < length; i++) { - map.put(i, Array.get(array, i)); - } - return map.entrySet(); - } - - /** - * Returns an iterator over a set of elements of type T. - * - * @return an Iterator. - */ - @Override - public Iterator iterator() { - return new ArrayObjectIterator(array); - } - - - } - - static class CollectionMap extends AbstractMap implements Iterable { - - private final Collection col; - - public CollectionMap(Collection col) { - this.col = col; - } - - @Override - public Object get(Object key) { - if (key instanceof Number) { - return Iterables.get(col, ((Number) key).intValue()); - } - try { - int index = Integer.parseInt(key.toString()); - return Iterables.get(col, index); - } catch (NumberFormatException nfe) { - // if it's not a number it is as if the key doesn't exist - return null; - } - } - - @Override - public boolean containsKey(Object key) { - return get(key) != null; - } - - @Override - public Set> entrySet() { - Map map = new HashMap<>(col.size()); - int i = 0; - for (Object item : col) { - map.put(i++, item); - } - return map.entrySet(); - } - - /** - * Returns an iterator over a set of elements of type T. - * - * @return an Iterator. - */ - @Override - public Iterator iterator() { - return col.iterator(); - } - } - - -} diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/xmustache/XMustacheScriptEngineService.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/xmustache/XMustacheScriptEngineService.java deleted file mode 100644 index d47523a5cea..00000000000 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/support/text/xmustache/XMustacheScriptEngineService.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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.watcher.support.text.xmustache; - -import com.github.mustachejava.Mustache; -import org.elasticsearch.common.Nullable; -import org.elasticsearch.common.component.AbstractComponent; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.FastStringReader; -import org.elasticsearch.common.io.UTF8StreamWriter; -import org.elasticsearch.common.io.stream.BytesStreamOutput; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.script.CompiledScript; -import org.elasticsearch.script.ExecutableScript; -import org.elasticsearch.script.ScriptEngineService; -import org.elasticsearch.script.SearchScript; -import org.elasticsearch.search.lookup.SearchLookup; - -import java.io.IOException; -import java.lang.ref.SoftReference; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -/** - * - */ -public class XMustacheScriptEngineService extends AbstractComponent implements ScriptEngineService { - - public static final String NAME = "xmustache"; - - public static final List TYPES = Collections.singletonList(NAME); - - /** - * @param settings automatically wired by Guice. - * */ - @Inject - public XMustacheScriptEngineService(Settings settings) { - super(settings); - } - - /** - * Compile a template string to (in this case) a Mustache object than can - * later be re-used for execution to fill in missing parameter values. - * - * @param template - * a string representing the template to compile. - * @return a compiled template object for later execution. - * */ - @Override - public Object compile(String template, Map params) { - /** Factory to generate Mustache objects from. */ - XContentType xContentType = detectContentType(template); - template = trimContentType(template); - return (new XMustacheFactory(xContentType)).compile(new FastStringReader(template), "query-template"); - } - - @Override - public List getTypes() { - return TYPES; - } - - @Override - public List getExtensions() { - return TYPES; - } - - @Override - public boolean isSandboxed() { - return true; - } - - @Override - public ExecutableScript executable(CompiledScript compiledScript, - @Nullable Map vars) { - return new MustacheExecutableScript((Mustache) compiledScript.compiled(), vars); - } - - @Override - public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, - @Nullable Map vars) { - throw new UnsupportedOperationException(); - } - - @Override - public void close() { - // Nothing to do here - } - - @Override - public void scriptRemoved(CompiledScript script) { - // Nothing to do here - } - - public static String prepareTemplate(String template, @Nullable XContentType contentType) { - if (contentType == null) { - return template; - } - return new StringBuilder("__") - .append(contentType.shortName().toLowerCase(Locale.ROOT)) - .append("__::") - .append(template) - .toString(); - } - - /** - * Used at query execution time by script service in order to execute a query template. - * */ - private class MustacheExecutableScript implements ExecutableScript { - /** Compiled template object. */ - private Mustache mustache; - /** Parameters to fill above object with. */ - private Map vars; - - /** - * @param mustache the compiled template object - * @param vars the parameters to fill above object with - **/ - public MustacheExecutableScript(Mustache mustache, - Map vars) { - this.mustache = mustache; - this.vars = vars == null ? Collections.emptyMap() : vars; - } - - @Override - public void setNextVar(String name, Object value) { - this.vars.put(name, value); - } - - @Override - public Object run() { - BytesStreamOutput result = new BytesStreamOutput(); - UTF8StreamWriter writer = utf8StreamWriter().setOutput(result); - mustache.execute(writer, vars); - try { - writer.flush(); - } catch (IOException e) { - logger.error("Could not execute query template (failed to flush writer): ", e); - } finally { - try { - writer.close(); - } catch (IOException e) { - logger.error("Could not execute query template (failed to close writer): ", e); - } - } - return result.bytes(); - } - - @Override - public Object unwrap(Object value) { - return value; - } - } - - /** Thread local UTF8StreamWriter to store template execution results in, thread local to save object creation.*/ - private static ThreadLocal> utf8StreamWriter = new ThreadLocal<>(); - - /** If exists, reset and return, otherwise create, reset and return a writer.*/ - private static UTF8StreamWriter utf8StreamWriter() { - SoftReference ref = utf8StreamWriter.get(); - UTF8StreamWriter writer = (ref == null) ? null : ref.get(); - if (writer == null) { - writer = new UTF8StreamWriter(1024 * 4); - utf8StreamWriter.set(new SoftReference<>(writer)); - } - writer.reset(); - return writer; - } - - private String trimContentType(String template) { - if (!template.startsWith("__")){ - return template; //Doesn't even start with __ so can't have a content type - } - int index = template.indexOf("__::", 3); //There must be a __= 0 && index < 12) { //Assume that the content type name is less than 10 characters long otherwise we may falsely detect strings that start with '__ and have '__::' somewhere in the content - if (template.length() == 6) { - template = ""; - } else { - template = template.substring(index + 4); - } - } - return template; - } - - private XContentType detectContentType(String template) { - if (template.startsWith("__")) { - int endOfContentName = template.indexOf("__::", 3); //There must be a __ model) { - Map mergedModel = new HashMap<>(); - mergedModel.putAll(template.getParams()); - mergedModel.putAll(model); - ExecutableScript executable = service.executable(new org.elasticsearch.script.Template(template.getTemplate(), template.getType(), XMustacheScriptEngineService.NAME, template.getContentType(), mergedModel)); - Object result = executable.run(); - if (result instanceof BytesReference) { - return ((BytesReference) result).toUtf8(); - } - return result.toString(); - } -} diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/MockMustacheScriptEngine.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/MockMustacheScriptEngine.java new file mode 100644 index 00000000000..981a7d7d799 --- /dev/null +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/MockMustacheScriptEngine.java @@ -0,0 +1,55 @@ +/* + * 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.script; + +import org.elasticsearch.common.Nullable; +import org.elasticsearch.search.lookup.SearchLookup; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * A mock script engine that registers itself under the 'mustache' name so that {@link org.elasticsearch.watcher.support.text.DefaultTextTemplateEngine} + * uses it and adds validation that watcher tests don't rely on mustache templating/ + */ +public class MockMustacheScriptEngine extends MockScriptEngine { + + public static final String NAME = "mustache"; + + public static class TestPlugin extends MockScriptEngine.TestPlugin { + + @Override + public String name() { + return NAME; + } + + public void onModule(ScriptModule module) { + module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(MockMustacheScriptEngine.class, Collections.singletonList(NAME))); + } + + } + + @Override + public List getTypes() { + return Collections.singletonList(NAME); + } + + @Override + public List getExtensions() { + return getTypes(); + } + + @Override + public Object compile(String script, Map params) { + if (script.contains("{{") && script.contains("}}")) { + throw new IllegalArgumentException("Fix your test to not rely on mustache"); + } + + return script; + } + +} diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/TimeThrottleIntegrationTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/TimeThrottleIntegrationTests.java similarity index 94% rename from elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/TimeThrottleIntegrationTests.java rename to elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/TimeThrottleIntegrationTests.java index df007830718..8d0b248bde5 100644 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/TimeThrottleIntegrationTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/TimeThrottleIntegrationTests.java @@ -3,13 +3,10 @@ * 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.messy.tests; - +package org.elasticsearch.watcher.actions; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.script.mustache.MustachePlugin; import org.elasticsearch.watcher.client.WatcherClient; import org.elasticsearch.watcher.condition.compare.CompareCondition; import org.elasticsearch.watcher.execution.ExecutionState; @@ -20,8 +17,6 @@ import org.elasticsearch.watcher.transport.actions.put.PutWatchResponse; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.TimeUnit; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; @@ -41,14 +36,6 @@ import static org.hamcrest.Matchers.is; */ public class TimeThrottleIntegrationTests extends AbstractWatcherIntegrationTestCase { - @Override - protected List> pluginTypes() { - List> types = new ArrayList<>(); - types.addAll(super.pluginTypes()); - types.add(MustachePlugin.class); - return types; - } - private IndexResponse indexTestDoc() { createIndex("actions", "events"); ensureGreen("actions", "events"); diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/EmailActionTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/EmailActionTests.java index ee4066843bd..a5e5ea99c32 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/EmailActionTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/EmailActionTests.java @@ -35,7 +35,6 @@ import org.elasticsearch.watcher.execution.Wid; import org.elasticsearch.watcher.support.http.HttpClient; import org.elasticsearch.watcher.support.http.HttpRequest; import org.elasticsearch.watcher.support.http.HttpRequestTemplate; -import org.elasticsearch.watcher.support.http.HttpRequestTemplateTests; import org.elasticsearch.watcher.support.http.HttpResponse; import org.elasticsearch.watcher.support.http.auth.HttpAuthRegistry; import org.elasticsearch.watcher.support.http.auth.basic.BasicAuthFactory; @@ -45,6 +44,7 @@ import org.elasticsearch.watcher.support.text.TextTemplate; import org.elasticsearch.watcher.support.text.TextTemplateEngine; import org.elasticsearch.watcher.support.xcontent.WatcherParams; import org.elasticsearch.watcher.test.AbstractWatcherIntegrationTestCase; +import org.elasticsearch.watcher.test.MockTextTemplateEngine; import org.elasticsearch.watcher.watch.Payload; import org.jboss.netty.handler.codec.http.HttpHeaders; import org.joda.time.DateTime; @@ -90,7 +90,7 @@ public class EmailActionTests extends ESTestCase { @Before public void addEmailAttachmentParsers() { - emailAttachmentParsers.put(HttpEmailAttachementParser.TYPE, new HttpEmailAttachementParser(httpClient, new HttpRequestTemplate.Parser(registry), new HttpRequestTemplateTests.MockTextTemplateEngine())); + emailAttachmentParsers.put(HttpEmailAttachementParser.TYPE, new HttpEmailAttachementParser(httpClient, new HttpRequestTemplate.Parser(registry), new MockTextTemplateEngine())); emailAttachmentParsers.put(DataAttachmentParser.TYPE, new DataAttachmentParser()); emailAttachmentParser = new EmailAttachmentsParser(emailAttachmentParsers); } diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/EmailAttachmentTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/EmailAttachmentTests.java similarity index 96% rename from elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/EmailAttachmentTests.java rename to elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/EmailAttachmentTests.java index 885fa4c33c6..defca60875f 100644 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/EmailAttachmentTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/EmailAttachmentTests.java @@ -3,7 +3,7 @@ * 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.messy.tests; +package org.elasticsearch.watcher.actions.email; import com.squareup.okhttp.mockwebserver.MockResponse; import com.squareup.okhttp.mockwebserver.MockWebServer; @@ -14,8 +14,6 @@ import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.script.mustache.MustachePlugin; import org.elasticsearch.watcher.actions.email.service.EmailTemplate; import org.elasticsearch.watcher.actions.email.service.attachment.DataAttachment; import org.elasticsearch.watcher.actions.email.service.attachment.EmailAttachmentParser; @@ -87,14 +85,6 @@ public class EmailAttachmentTests extends AbstractWatcherIntegrationTestCase { webServer.shutdown(); } - @Override - protected List> pluginTypes() { - List> types = new ArrayList<>(); - types.addAll(super.pluginTypes()); - types.add(MustachePlugin.class); - return types; - } - @Override protected Settings nodeSettings(int nodeOrdinal) { if(server == null) { diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/service/attachment/HttpEmailAttachementParserTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/service/attachment/HttpEmailAttachementParserTests.java index 35db6a610a3..3d64564f814 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/service/attachment/HttpEmailAttachementParserTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/service/attachment/HttpEmailAttachementParserTests.java @@ -13,12 +13,12 @@ import org.elasticsearch.test.ESTestCase; import org.elasticsearch.watcher.support.http.HttpClient; import org.elasticsearch.watcher.support.http.HttpRequest; import org.elasticsearch.watcher.support.http.HttpRequestTemplate; -import org.elasticsearch.watcher.support.http.HttpRequestTemplateTests; import org.elasticsearch.watcher.support.http.HttpResponse; import org.elasticsearch.watcher.support.http.auth.HttpAuthRegistry; import org.elasticsearch.watcher.support.http.auth.basic.BasicAuth; import org.elasticsearch.watcher.support.http.auth.basic.BasicAuthFactory; import org.elasticsearch.watcher.support.secret.SecretService; +import org.elasticsearch.watcher.test.MockTextTemplateEngine; import org.junit.Before; import java.util.HashMap; @@ -54,7 +54,7 @@ public class HttpEmailAttachementParserTests extends ESTestCase { public void testSerializationWorks() throws Exception { Map attachmentParsers = new HashMap<>(); - attachmentParsers.put(HttpEmailAttachementParser.TYPE, new HttpEmailAttachementParser(httpClient, httpRequestTemplateParser, new HttpRequestTemplateTests.MockTextTemplateEngine())); + attachmentParsers.put(HttpEmailAttachementParser.TYPE, new HttpEmailAttachementParser(httpClient, httpRequestTemplateParser, new MockTextTemplateEngine())); EmailAttachmentsParser emailAttachmentsParser = new EmailAttachmentsParser(attachmentParsers); String id = "some-id"; diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/slack/service/message/SlackMessageTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/slack/service/message/SlackMessageTests.java index 1a4d2736f9e..3161253ce08 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/slack/service/message/SlackMessageTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/slack/service/message/SlackMessageTests.java @@ -13,6 +13,7 @@ import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.watcher.support.text.TextTemplate; import org.elasticsearch.watcher.support.text.TextTemplateEngine; +import org.elasticsearch.watcher.test.MockTextTemplateEngine; import java.io.IOException; import java.util.ArrayList; @@ -441,12 +442,7 @@ public class SlackMessageTests extends ESTestCase { } // relies on the fact that all the templates we use are inline templates without param place holders - TextTemplateEngine engine = new TextTemplateEngine() { - @Override - public String render(TextTemplate template, Map model) { - return template.getTemplate(); - } - }; + TextTemplateEngine engine = new MockTextTemplateEngine(); SlackMessage.Template template = templateBuilder.build(); diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/throttler/ActionThrottleTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/throttler/ActionThrottleTests.java index 725b23429a5..26ab8348ca7 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/throttler/ActionThrottleTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/throttler/ActionThrottleTests.java @@ -385,7 +385,7 @@ public class ActionThrottleTests extends AbstractWatcherIntegrationTestCase { LOGGING { @Override public Action.Builder action() throws Exception { - TextTemplate.Builder templateBuilder = new TextTemplate.Builder.Inline("{{ctx.watch_id}}"); + TextTemplate.Builder templateBuilder = new TextTemplate.Builder.Inline("_logging"); return LoggingAction.builder(templateBuilder.build()); } diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookActionTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookActionTests.java index 72eaa2c107f..479c0fcb746 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookActionTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookActionTests.java @@ -37,8 +37,9 @@ import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy; import org.elasticsearch.watcher.support.secret.SecretService; import org.elasticsearch.watcher.support.text.TextTemplate; import org.elasticsearch.watcher.support.text.TextTemplateEngine; -import org.elasticsearch.watcher.support.text.xmustache.XMustacheTextTemplateEngine; +import org.elasticsearch.watcher.support.text.DefaultTextTemplateEngine; import org.elasticsearch.watcher.test.AbstractWatcherIntegrationTestCase; +import org.elasticsearch.watcher.test.MockTextTemplateEngine; import org.elasticsearch.watcher.test.WatcherTestUtils; import org.elasticsearch.watcher.trigger.schedule.ScheduleTriggerEvent; import org.elasticsearch.watcher.watch.Payload; @@ -50,7 +51,6 @@ import org.junit.Before; import javax.mail.internet.AddressException; import java.io.IOException; -import java.util.HashMap; import java.util.Map; import static java.util.Collections.singletonMap; @@ -78,8 +78,6 @@ public class WebhookActionTests extends ESTestCase { static final String TEST_HOST = "test.com"; static final int TEST_PORT = 8089; - private ThreadPool tp = null; - private ScriptServiceProxy scriptService; private TextTemplateEngine templateEngine; private HttpAuthRegistry authRegistry; private TextTemplate testBody; @@ -91,21 +89,13 @@ public class WebhookActionTests extends ESTestCase { @Before public void init() throws Exception { - tp = new ThreadPool(ThreadPool.Names.SAME); - Settings settings = Settings.EMPTY; - scriptService = WatcherTestUtils.getScriptServiceProxy(tp); - templateEngine = new XMustacheTextTemplateEngine(settings, scriptService); + templateEngine = new MockTextTemplateEngine(); SecretService secretService = mock(SecretService.class); testBody = TextTemplate.inline(TEST_BODY_STRING).build(); testPath = TextTemplate.inline(TEST_PATH_STRING).build(); authRegistry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(secretService))); } - @After - public void cleanup() { - tp.shutdownNow(); - } - public void testExecute() throws Exception { ExecuteScenario scenario = randomFrom(ExecuteScenario.Success, ExecuteScenario.ErrorCode); @@ -236,56 +226,6 @@ public class WebhookActionTests extends ESTestCase { return new WebhookActionFactory(Settings.EMPTY, client, new HttpRequestTemplate.Parser(authRegistry), templateEngine); } - public void testTemplatedHttpRequest() throws Exception { - HttpClient httpClient = ExecuteScenario.Success.client(); - - String body = "{{ctx.watch_id}}"; - String host = "testhost"; - String path = randomFrom("{{ctx.execution_time}}", "{{ctx.trigger.scheduled_time}}", "{{ctx.trigger.triggered_time}}"); - - Map params = new HashMap<>(); - params.put("foo", TextTemplate.inline(randomFrom("{{ctx.execution_time}}", "{{ctx.trigger.scheduled_time}}", "{{ctx.trigger.triggered_time}}")).build()); - HttpMethod method = randomFrom(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT); - - HttpRequestTemplate request = getHttpRequestTemplate(method, host, TEST_PORT, TextTemplate.inline(path).build(), TextTemplate.inline(body).build(), params); - - String watchId = "_watch"; - String actionId = randomAsciiOfLength(5); - - WebhookAction action = WebhookAction.builder(request).build(); - - ExecutableWebhookAction webhookAction = new ExecutableWebhookAction(action, logger, httpClient, templateEngine); - - DateTime time = new DateTime(UTC); - Watch watch = createWatch(watchId, mock(ClientProxy.class), "account1"); - WatchExecutionContext ctx = new TriggeredExecutionContext(watch, time, new ScheduleTriggerEvent(watchId, time, time), timeValueSeconds(5)); - Action.Result result = webhookAction.execute(actionId, ctx, Payload.EMPTY); - - assertThat(result, Matchers.instanceOf(WebhookAction.Result.Success.class)); - WebhookAction.Result.Success success = (WebhookAction.Result.Success) result; - assertThat(success.request().body(), equalTo(watchId)); - assertThat(success.request().path(), equalTo(time.toString())); - assertThat(success.request().params().get("foo"), equalTo(time.toString())); - - } - - public void testValidUrls() throws Exception { - HttpClient httpClient = ExecuteScenario.Success.client(); - HttpMethod method = HttpMethod.POST; - TextTemplate path = TextTemplate.defaultType("/test_{{ctx.watch_id}}").build(); - String host = "test.host"; - HttpRequestTemplate requestTemplate = getHttpRequestTemplate(method, host, TEST_PORT, path, testBody, null); - WebhookAction action = new WebhookAction(requestTemplate); - - ExecutableWebhookAction executable = new ExecutableWebhookAction(action, logger, httpClient, templateEngine); - - String watchId = "test_url_encode" + randomAsciiOfLength(10); - Watch watch = createWatch(watchId, mock(ClientProxy.class), "account1"); - WatchExecutionContext ctx = new TriggeredExecutionContext(watch, new DateTime(UTC), new ScheduleTriggerEvent(watchId, new DateTime(UTC), new DateTime(UTC)), timeValueSeconds(5)); - Action.Result result = executable.execute("_id", ctx, new Payload.Simple()); - assertThat(result, Matchers.instanceOf(WebhookAction.Result.Success.class)); - } - public void testThatSelectingProxyWorks() throws Exception { Environment environment = new Environment(Settings.builder().put("path.home", createTempDir()).build()); HttpClient httpClient = new HttpClient(Settings.EMPTY, authRegistry, environment).start(); @@ -311,10 +251,30 @@ public class WebhookActionTests extends ESTestCase { } } + public void testValidUrls() throws Exception { + HttpClient client = mock(HttpClient.class); + when(client.execute(any(HttpRequest.class))) + .thenReturn(new HttpResponse(randomIntBetween(200, 399))); + String watchId = "test_url_encode" + randomAsciiOfLength(10); + + HttpMethod method = HttpMethod.POST; + TextTemplate path = TextTemplate.defaultType("/test_" + watchId).build(); + String host = "test.host"; + TextTemplate testBody = TextTemplate.inline("ERROR HAPPENED").build(); + HttpRequestTemplate requestTemplate = getHttpRequestTemplate(method, host, TEST_PORT, path, testBody, null); + WebhookAction action = new WebhookAction(requestTemplate); + + ExecutableWebhookAction executable = new ExecutableWebhookAction(action, logger, client, templateEngine); + + Watch watch = createWatch(watchId, mock(ClientProxy.class), "account1"); + WatchExecutionContext ctx = new TriggeredExecutionContext(watch, new DateTime(UTC), new ScheduleTriggerEvent(watchId, new DateTime(UTC), new DateTime(UTC)), timeValueSeconds(5)); + Action.Result result = executable.execute("_id", ctx, new Payload.Simple()); + assertThat(result, Matchers.instanceOf(WebhookAction.Result.Success.class)); + } + private Watch createWatch(String watchId, ClientProxy client, final String account) throws AddressException, IOException { return WatcherTestUtils.createTestWatch(watchId, client, - scriptService, ExecuteScenario.Success.client(), new AbstractWatcherIntegrationTestCase.NoopEmailService() { @Override diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookHttpsIntegrationTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookHttpsIntegrationTests.java index 532e53236f4..04612e4c741 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookHttpsIntegrationTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookHttpsIntegrationTests.java @@ -83,8 +83,8 @@ public class WebhookHttpsIntegrationTests extends AbstractWatcherIntegrationTest webServer.enqueue(new MockResponse().setResponseCode(200).setBody("body")); HttpRequestTemplate.Builder builder = HttpRequestTemplate.builder("localhost", webPort) .scheme(Scheme.HTTPS) - .path(TextTemplate.inline("/test/{{ctx.watch_id}}").build()) - .body(TextTemplate.inline("{{ctx.payload}}").build()); + .path(TextTemplate.inline("/test/_id").build()) + .body(TextTemplate.inline("{key=value}").build()); watcherClient().preparePutWatch("_id") .setSource(watchBuilder() @@ -126,8 +126,8 @@ public class WebhookHttpsIntegrationTests extends AbstractWatcherIntegrationTest HttpRequestTemplate.Builder builder = HttpRequestTemplate.builder("localhost", webPort) .scheme(Scheme.HTTPS) .auth(new BasicAuth("_username", "_password".toCharArray())) - .path(TextTemplate.inline("/test/{{ctx.watch_id}}").build()) - .body(TextTemplate.inline("{{ctx.payload}}").build()); + .path(TextTemplate.inline("/test/_id").build()) + .body(TextTemplate.inline("{key=value}").build()); watcherClient().preparePutWatch("_id") .setSource(watchBuilder() diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookIntegrationTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookIntegrationTests.java index 98b23ce8b8f..a9ee9248018 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookIntegrationTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookIntegrationTests.java @@ -70,10 +70,10 @@ public class WebhookIntegrationTests extends AbstractWatcherIntegrationTestCase public void testWebhook() throws Exception { webServer.enqueue(new MockResponse().setResponseCode(200).setBody("body")); HttpRequestTemplate.Builder builder = HttpRequestTemplate.builder("localhost", webPort) - .path(TextTemplate.inline("/test/{{ctx.watch_id}}")) + .path(TextTemplate.inline("/test/_id")) .putParam("param1", TextTemplate.inline("value1")) - .putParam("watch_id", TextTemplate.inline("{{ctx.watch_id}}")) - .body(TextTemplate.inline("{{ctx.payload}}")); + .putParam("watch_id", TextTemplate.inline("_id")) + .body(TextTemplate.inline("_body")); watcherClient().preparePutWatch("_id") .setSource(watchBuilder() @@ -91,7 +91,7 @@ public class WebhookIntegrationTests extends AbstractWatcherIntegrationTestCase assertWatchWithMinimumPerformedActionsCount("_id", 1, false); RecordedRequest recordedRequest = webServer.takeRequest(); assertThat(recordedRequest.getPath(), anyOf(equalTo("/test/_id?watch_id=_id¶m1=value1"), equalTo("/test/_id?param1=value1&watch_id=_id"))); - assertThat(recordedRequest.getBody().readUtf8Line(), equalTo("{key=value}")); + assertThat(recordedRequest.getBody().readUtf8Line(), equalTo("_body")); SearchResponse response = searchWatchRecords(new Callback() { @Override @@ -114,10 +114,10 @@ public class WebhookIntegrationTests extends AbstractWatcherIntegrationTestCase webServer.enqueue(new MockResponse().setResponseCode(200).setBody("body")); HttpRequestTemplate.Builder builder = HttpRequestTemplate.builder("localhost", webPort) .auth(new BasicAuth("_username", "_password".toCharArray())) - .path(TextTemplate.inline("/test/{{ctx.watch_id}}").build()) + .path(TextTemplate.inline("/test/_id").build()) .putParam("param1", TextTemplate.inline("value1").build()) - .putParam("watch_id", TextTemplate.inline("{{ctx.watch_id}}").build()) - .body(TextTemplate.inline("{{ctx.payload}}").build()); + .putParam("watch_id", TextTemplate.inline("_id").build()) + .body(TextTemplate.inline("_body").build()); watcherClient().preparePutWatch("_id") .setSource(watchBuilder() @@ -135,7 +135,7 @@ public class WebhookIntegrationTests extends AbstractWatcherIntegrationTestCase assertWatchWithMinimumPerformedActionsCount("_id", 1, false); RecordedRequest recordedRequest = webServer.takeRequest(); assertThat(recordedRequest.getPath(), anyOf(equalTo("/test/_id?watch_id=_id¶m1=value1"), equalTo("/test/_id?param1=value1&watch_id=_id"))); - assertThat(recordedRequest.getBody().readUtf8Line(), equalTo("{key=value}")); + assertThat(recordedRequest.getBody().readUtf8Line(), equalTo("_body")); assertThat(recordedRequest.getHeader("Authorization"), equalTo("Basic X3VzZXJuYW1lOl9wYXNzd29yZA==")); } } diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/execution/TriggeredWatchTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/execution/TriggeredWatchTests.java index 1c97f9cc138..68552575042 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/execution/TriggeredWatchTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/execution/TriggeredWatchTests.java @@ -21,7 +21,7 @@ import static org.hamcrest.Matchers.equalTo; */ public class TriggeredWatchTests extends AbstractWatcherIntegrationTestCase { public void testParser() throws Exception { - Watch watch = WatcherTestUtils.createTestWatch("fired_test", scriptService(), watcherHttpClient(), noopEmailService(), logger); + Watch watch = WatcherTestUtils.createTestWatch("fired_test", watcherHttpClient(), noopEmailService(), logger); ScheduleTriggerEvent event = new ScheduleTriggerEvent(watch.id(), DateTime.now(DateTimeZone.UTC), DateTime.now(DateTimeZone.UTC)); Wid wid = new Wid("_record", randomLong(), DateTime.now(DateTimeZone.UTC)); TriggeredWatch triggeredWatch = new TriggeredWatch(wid, event); diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/HistoryTemplateSearchInputMappingsTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/history/HistoryTemplateSearchInputMappingsTests.java similarity index 90% rename from elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/HistoryTemplateSearchInputMappingsTests.java rename to elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/history/HistoryTemplateSearchInputMappingsTests.java index 976be71675f..06effa551b2 100644 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/HistoryTemplateSearchInputMappingsTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/history/HistoryTemplateSearchInputMappingsTests.java @@ -3,23 +3,17 @@ * 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.messy.tests; +package org.elasticsearch.watcher.history; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchType; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.script.mustache.MustachePlugin; import org.elasticsearch.search.aggregations.Aggregations; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.watcher.execution.ExecutionState; -import org.elasticsearch.watcher.history.HistoryStore; import org.elasticsearch.watcher.test.AbstractWatcherIntegrationTestCase; import org.elasticsearch.watcher.transport.actions.put.PutWatchResponse; -import java.util.ArrayList; -import java.util.List; - import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.search.aggregations.AggregationBuilders.terms; import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource; @@ -38,14 +32,6 @@ import static org.hamcrest.Matchers.notNullValue; */ public class HistoryTemplateSearchInputMappingsTests extends AbstractWatcherIntegrationTestCase { - @Override - protected List> pluginTypes() { - List> types = new ArrayList<>(); - types.addAll(super.pluginTypes()); - types.add(MustachePlugin.class); - return types; - } - @Override protected boolean timeWarped() { return true; // just to have better control over the triggers diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/input/chain/ChainIntegrationTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/input/chain/ChainIntegrationTests.java index 7988a3b39ad..5a57dee4727 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/input/chain/ChainIntegrationTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/input/chain/ChainIntegrationTests.java @@ -47,7 +47,7 @@ public class ChainIntegrationTests extends AbstractWatcherIntegrationTestCase { InetSocketAddress address = internalCluster().httpAddresses()[0]; HttpInput.Builder httpInputBuilder = httpInput(HttpRequestTemplate.builder(address.getHostString(), address.getPort()) - .path("{{ctx.payload.first.url}}") + .path("/" + index + "/_search") .body(jsonBuilder().startObject().field("size", 1).endObject()) .auth(shieldEnabled() ? new BasicAuth("test", "changeme".toCharArray()) : null)); diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/support/http/HttpRequestTemplateTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/support/http/HttpRequestTemplateTests.java index 52b28e5c7f7..5cfdeed193c 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/support/http/HttpRequestTemplateTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/support/http/HttpRequestTemplateTests.java @@ -5,27 +5,22 @@ */ package org.elasticsearch.watcher.support.http; -import com.google.common.collect.Lists; -import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.common.xcontent.json.JsonXContent; -import org.elasticsearch.search.aggregations.support.format.ValueParser; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.watcher.support.http.auth.HttpAuthRegistry; import org.elasticsearch.watcher.support.http.auth.basic.BasicAuth; import org.elasticsearch.watcher.support.http.auth.basic.BasicAuthFactory; import org.elasticsearch.watcher.support.secret.SecretService; import org.elasticsearch.watcher.support.text.TextTemplate; -import org.elasticsearch.watcher.support.text.TextTemplateEngine; +import org.elasticsearch.watcher.test.MockTextTemplateEngine; import org.jboss.netty.handler.codec.http.HttpHeaders; import java.util.Collections; -import java.util.HashMap; -import java.util.Map; import static java.util.Collections.emptyMap; import static java.util.Collections.singletonMap; @@ -66,6 +61,21 @@ public class HttpRequestTemplateTests extends ESTestCase { assertThat(request.proxy().getPort(), is(8080)); } + public void testRender() { + HttpRequestTemplate template = HttpRequestTemplate.builder("_host", 1234) + .body(TextTemplate.inline("_body")) + .path(TextTemplate.inline("_path")) + .putParam("_key1", TextTemplate.inline("_value1")) + .putHeader("_key2", TextTemplate.inline("_value2")) + .build(); + + HttpRequest result = template.render(new MockTextTemplateEngine(), Collections.emptyMap()); + assertThat(result.body(), equalTo("_body")); + assertThat(result.path(), equalTo("_path")); + assertThat(result.params(), equalTo(Collections.singletonMap("_key1", "_value1"))); + assertThat(result.headers(), equalTo(Collections.singletonMap("_key2", "_value2"))); + } + public void testProxyParsing() throws Exception { HttpRequestTemplate.Builder builder = HttpRequestTemplate.builder("_host", 1234); builder.path("/path"); @@ -169,10 +179,4 @@ public class HttpRequestTemplateTests extends ESTestCase { assertThat(parsedTemplate, is(urlParsedTemplate)); } - public static class MockTextTemplateEngine implements TextTemplateEngine { - @Override - public String render(TextTemplate template, Map model) { - return template.getTemplate(); - } - } } diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/support/text/TextTemplateTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/support/text/TextTemplateTests.java index 3e404ee4439..5f9a90d5584 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/support/text/TextTemplateTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/support/text/TextTemplateTests.java @@ -12,13 +12,18 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.json.JsonXContent; +import org.elasticsearch.script.CompiledScript; import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.ScriptService.ScriptType; +import org.elasticsearch.script.Template; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy; -import org.elasticsearch.watcher.support.text.xmustache.XMustacheTextTemplateEngine; +import org.elasticsearch.watcher.support.text.DefaultTextTemplateEngine; +import org.elasticsearch.watcher.support.text.TextTemplate; +import org.elasticsearch.watcher.support.text.TextTemplateEngine; import org.junit.Before; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -32,20 +37,18 @@ import static org.hamcrest.Matchers.notNullValue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -/** - * - */ public class TextTemplateTests extends ESTestCase { + private ScriptServiceProxy proxy; private TextTemplateEngine engine; private ExecutableScript script; - private final String lang = "xmustache"; + private final String lang = "mustache"; @Before public void init() throws Exception { proxy = mock(ScriptServiceProxy.class); script = mock(ExecutableScript.class); - engine = new XMustacheTextTemplateEngine(Settings.EMPTY, proxy); + engine = new DefaultTextTemplateEngine(Settings.EMPTY, proxy); } public void testRender() throws Exception { @@ -57,7 +60,9 @@ public class TextTemplateTests extends ESTestCase { merged = unmodifiableMap(merged); ScriptType type = randomFrom(ScriptType.values()); - when(proxy.executable(new org.elasticsearch.script.Template(templateText, type, lang, null, merged))).thenReturn(script); + CompiledScript compiledScript = mock(CompiledScript.class); + when(proxy.compile(new Template(templateText, type, lang, null, merged), Collections.singletonMap("content_type", "text/plain"))).thenReturn(compiledScript); + when(proxy.executable(compiledScript, model)).thenReturn(script); when(script.run()).thenReturn("rendered_text"); TextTemplate template = templateBuilder(type, templateText).params(params).build(); @@ -70,7 +75,9 @@ public class TextTemplateTests extends ESTestCase { Map model = singletonMap("key", "model_val"); ScriptType scriptType = randomFrom(ScriptType.values()); - when(proxy.executable(new org.elasticsearch.script.Template(templateText, scriptType, lang, null, model))).thenReturn(script); + CompiledScript compiledScript = mock(CompiledScript.class); + when(proxy.compile(new Template(templateText, scriptType, lang, null, model), Collections.singletonMap("content_type", "text/plain"))).thenReturn(compiledScript); + when(proxy.executable(compiledScript, model)).thenReturn(script); when(script.run()).thenReturn("rendered_text"); TextTemplate template = templateBuilder(scriptType, templateText).params(params).build(); @@ -81,7 +88,9 @@ public class TextTemplateTests extends ESTestCase { String templateText = "_template"; Map model = singletonMap("key", "model_val"); - when(proxy.executable(new org.elasticsearch.script.Template(templateText, ScriptType.INLINE, lang, null, model))).thenReturn(script); + CompiledScript compiledScript = mock(CompiledScript.class); + when(proxy.compile(new Template(templateText, ScriptType.INLINE, lang, null, model), Collections.singletonMap("content_type", "text/plain"))).thenReturn(compiledScript); + when(proxy.executable(compiledScript, model)).thenReturn(script); when(script.run()).thenReturn("rendered_text"); TextTemplate template = new TextTemplate(templateText); diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/support/text/xmustache/XMustacheScriptEngineTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/support/text/xmustache/XMustacheScriptEngineTests.java deleted file mode 100644 index 848db7177c4..00000000000 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/support/text/xmustache/XMustacheScriptEngineTests.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.watcher.support.text.xmustache; - - -import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.script.CompiledScript; -import org.elasticsearch.script.ScriptService; -import org.elasticsearch.test.ESTestCase; -import org.junit.Before; - -import java.io.StringWriter; -import java.io.Writer; -import java.nio.charset.Charset; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -/** - * - */ -public class XMustacheScriptEngineTests extends ESTestCase { - private XMustacheScriptEngineService engine; - - @Before - public void setup() { - engine = new XMustacheScriptEngineService(Settings.Builder.EMPTY_SETTINGS); - } - - public void testSimpleParameterReplace() { - { - String template = "__json__::GET _search {\"query\": " + "{\"boosting\": {" + "\"positive\": {\"match\": {\"body\": \"gift\"}}," - + "\"negative\": {\"term\": {\"body\": {\"value\": \"solr\"}" + "}}, \"negative_boost\": {{boost_val}} } }}"; - Map vars = new HashMap<>(); - vars.put("boost_val", "0.3"); - CompiledScript compiledScript = new CompiledScript(ScriptService.ScriptType.INLINE, "inline", "mustache", engine.compile(template, Collections.emptyMap())); - BytesReference o = (BytesReference) engine.executable(compiledScript, vars).run(); - assertEquals("GET _search {\"query\": {\"boosting\": {\"positive\": {\"match\": {\"body\": \"gift\"}}," - + "\"negative\": {\"term\": {\"body\": {\"value\": \"solr\"}}}, \"negative_boost\": 0.3 } }}", - new String(o.toBytes(), Charset.forName("UTF-8"))); - } - { - String template = "__json__::GET _search {\"query\": " + "{\"boosting\": {" + "\"positive\": {\"match\": {\"body\": \"gift\"}}," - + "\"negative\": {\"term\": {\"body\": {\"value\": \"{{body_val}}\"}" + "}}, \"negative_boost\": {{boost_val}} } }}"; - Map vars = new HashMap<>(); - vars.put("boost_val", "0.3"); - vars.put("body_val", "\"quick brown\""); - CompiledScript compiledScript = new CompiledScript(ScriptService.ScriptType.INLINE, "inline", "mustache", engine.compile(template, Collections.emptyMap())); - BytesReference o = (BytesReference) engine.executable(compiledScript, vars).run(); - assertEquals("GET _search {\"query\": {\"boosting\": {\"positive\": {\"match\": {\"body\": \"gift\"}}," - + "\"negative\": {\"term\": {\"body\": {\"value\": \"\\\"quick brown\\\"\"}}}, \"negative_boost\": 0.3 } }}", - new String(o.toBytes(), Charset.forName("UTF-8"))); - } - } - - public void testInvalidPrefixes() throws Exception { - String[] specialStrings = new String[]{"\f", "\n", "\r", "\"", "\\", "\t", "\b", "__::", "__" }; - String prefix = randomFrom("", "__", "____::", "___::", "____", "::", "++json__::", "__json__", "+_json__::", "__json__:"); - String template = prefix + " {{test_var1}} {{test_var2}}"; - Map vars = new HashMap<>(); - Writer var1Writer = new StringWriter(); - Writer var2Writer = new StringWriter(); - - for(int i = 0; i < scaledRandomIntBetween(10,1000); ++i) { - var1Writer.write(randomRealisticUnicodeOfCodepointLengthBetween(0, 10)); - var2Writer.write(randomRealisticUnicodeOfCodepointLengthBetween(0, 10)); - var1Writer.append(randomFrom(specialStrings)); - var2Writer.append(randomFrom(specialStrings)); - } - - vars.put("test_var1", var1Writer.toString()); - vars.put("test_var2", var2Writer.toString()); - CompiledScript compiledScript = new CompiledScript(ScriptService.ScriptType.INLINE, "inline", "mustache", engine.compile(template, Collections.emptyMap())); - BytesReference o = (BytesReference) engine.executable(compiledScript, vars).run(); - String s1 = o.toUtf8(); - String s2 = prefix + " " + var1Writer.toString() + " " + var2Writer.toString(); - assertEquals(s1, s2); - } -} diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/support/text/xmustache/XMustacheTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/support/text/xmustache/XMustacheTests.java deleted file mode 100644 index 4cdca2429fb..00000000000 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/support/text/xmustache/XMustacheTests.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * 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.watcher.support.text.xmustache; - -import com.fasterxml.jackson.core.io.JsonStringEncoder; -import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.script.CompiledScript; -import org.elasticsearch.script.ScriptEngineService; -import org.elasticsearch.script.ScriptService; -import org.elasticsearch.test.ESTestCase; -import org.junit.Before; - -import java.io.IOException; -import java.io.StringWriter; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import static java.util.Collections.singleton; -import static java.util.Collections.singletonMap; -import static org.hamcrest.Matchers.both; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.notNullValue; - -/** - * - */ -public class XMustacheTests extends ESTestCase { - private ScriptEngineService engine; - - @Before - public void init() throws Exception { - engine = new XMustacheScriptEngineService(Settings.EMPTY); - } - - public void testArrayAccess() throws Exception { - String template = "{{data.0}} {{data.1}}"; - CompiledScript mustache = new CompiledScript(ScriptService.ScriptType.INLINE, "inline", "mustache", engine.compile(template, Collections.emptyMap())); - Map vars = new HashMap<>(); - Object data = randomFrom( - new String[] { "foo", "bar" }, - Arrays.asList("foo", "bar")); - vars.put("data", data); - Object output = engine.executable(mustache, vars).run(); - assertThat(output, notNullValue()); - assertThat(output, instanceOf(BytesReference.class)); - BytesReference bytes = (BytesReference) output; - assertThat(bytes.toUtf8(), equalTo("foo bar")); - - // Sets can come out in any order - Set setData = new HashSet<>(); - setData.add("foo"); - setData.add("bar"); - vars.put("data", setData); - output = engine.executable(mustache, vars).run(); - assertThat(output, notNullValue()); - assertThat(output, instanceOf(BytesReference.class)); - bytes = (BytesReference) output; - assertThat(bytes.toUtf8(), both(containsString("foo")).and(containsString("bar"))); - } - - public void testArrayInArrayAccess() throws Exception { - String template = "{{data.0.0}} {{data.0.1}}"; - CompiledScript mustache = new CompiledScript(ScriptService.ScriptType.INLINE, "inline", "mustache", engine.compile(template, Collections.emptyMap())); - Map vars = new HashMap<>(); - Object data = randomFrom( - new String[][] { new String[] { "foo", "bar" }}, - Collections.singletonList(new String[] { "foo", "bar" }), - singleton(new String[] { "foo", "bar" }) - ); - vars.put("data", data); - Object output = engine.executable(mustache, vars).run(); - assertThat(output, notNullValue()); - assertThat(output, instanceOf(BytesReference.class)); - BytesReference bytes = (BytesReference) output; - assertThat(bytes.toUtf8(), equalTo("foo bar")); - } - - public void testMapInArrayAccess() throws Exception { - String template = "{{data.0.key}} {{data.1.key}}"; - CompiledScript mustache = new CompiledScript(ScriptService.ScriptType.INLINE, "inline", "mustache", engine.compile(template, Collections.emptyMap())); - Map vars = new HashMap<>(); - Object data = randomFrom( - new Map[] { singletonMap("key", "foo"), singletonMap("key", "bar") }, - Arrays.asList(singletonMap("key", "foo"), singletonMap("key", "bar"))); - vars.put("data", data); - Object output = engine.executable(mustache, vars).run(); - assertThat(output, notNullValue()); - assertThat(output, instanceOf(BytesReference.class)); - BytesReference bytes = (BytesReference) output; - assertThat(bytes.toUtf8(), equalTo("foo bar")); - - // HashSet iteration order isn't fixed - Set setData = new HashSet<>(); - setData.add(singletonMap("key", "foo")); - setData.add(singletonMap("key", "bar")); - vars.put("data", setData); - output = engine.executable(mustache, vars).run(); - assertThat(output, notNullValue()); - assertThat(output, instanceOf(BytesReference.class)); - bytes = (BytesReference) output; - assertThat(bytes.toUtf8(), both(containsString("foo")).and(containsString("bar"))); - - } - - public void testEscaping() throws Exception { - XContentType contentType = randomFrom(XContentType.values()); - if (rarely()) { - contentType = null; - } - Character[] specialChars = new Character[]{'\f', '\n', '\r', '"', '\\', (char) 11, '\t', '\b' }; - int iters = scaledRandomIntBetween(100, 1000); - for (int i = 0; i < iters; i++) { - int rounds = scaledRandomIntBetween(1, 20); - StringWriter escaped = new StringWriter(); //This will be escaped as it is constructed - StringWriter unescaped = new StringWriter(); //This will be escaped at the end - - for (int j = 0; j < rounds; j++) { - String s = getChars(); - unescaped.write(s); - if (contentType == XContentType.JSON) { - escaped.write(JsonStringEncoder.getInstance().quoteAsString(s)); - } else { - escaped.write(s); - } - - char c = randomFrom(specialChars); - unescaped.append(c); - - if (contentType == XContentType.JSON) { - escaped.write(JsonStringEncoder.getInstance().quoteAsString("" + c)); - } else { - escaped.append(c); - } - } - - if (contentType == XContentType.JSON) { - assertThat(escaped.toString(), equalTo(new String(JsonStringEncoder.getInstance().quoteAsString(unescaped.toString())))); - } - else { - assertThat(escaped.toString(), equalTo(unescaped.toString())); - } - - String template = XMustacheScriptEngineService.prepareTemplate("{{data}}", contentType); - - Map dataMap = new HashMap<>(); - dataMap.put("data", unescaped.toString()); - CompiledScript mustache = new CompiledScript(ScriptService.ScriptType.INLINE, "inline", "mustache", engine.compile(template, Collections.emptyMap())); - Object output = engine.executable(mustache, dataMap).run(); - - assertThat(output, notNullValue()); - assertThat(output, instanceOf(BytesReference.class)); - BytesReference bytes = (BytesReference) output; - String renderedTemplate = bytes.toUtf8(); - - if (contentType == XContentType.JSON) { - if (!escaped.toString().equals(renderedTemplate)) { - String escapedString = escaped.toString(); - for (int l = 0; l < renderedTemplate.length() && l < escapedString.length(); ++l) { - if (renderedTemplate.charAt(l) != escapedString.charAt(l)) { - logger.error("at [{}] expected [{}] but got [{}]", l, renderedTemplate.charAt(l), escapedString.charAt(l)); - } - } - } - assertThat(escaped.toString(), equalTo(renderedTemplate)); - } else { - assertThat(unescaped.toString(), equalTo(renderedTemplate)); - } - } - } - - private String getChars() throws IOException { - return randomRealisticUnicodeOfCodepointLengthBetween(0, 10); - } -} diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/AbstractWatcherIntegrationTestCase.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/AbstractWatcherIntegrationTestCase.java index cea6b3fa9aa..6f57152cea4 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/AbstractWatcherIntegrationTestCase.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/AbstractWatcherIntegrationTestCase.java @@ -24,6 +24,7 @@ import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.index.IndexModule; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.script.MockMustacheScriptEngine; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.shield.ShieldPlugin; @@ -152,6 +153,7 @@ public abstract class AbstractWatcherIntegrationTestCase extends ESIntegTestCase plugins.remove(MockTransportService.TestPlugin.class); // shield has its own transport service plugins.remove(AssertingLocalTransport.TestPlugin.class); // shield has its own transport plugins.add(MockFSIndexStore.TestPlugin.class); // we have to explicitly add it otherwise we will fail to set the check_index_on_close setting + plugins.add(MockMustacheScriptEngine.TestPlugin.class); return plugins; } diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/MockTextTemplateEngine.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/MockTextTemplateEngine.java new file mode 100644 index 00000000000..c5236983706 --- /dev/null +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/MockTextTemplateEngine.java @@ -0,0 +1,18 @@ +/* + * 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.watcher.test; + +import org.elasticsearch.watcher.support.text.TextTemplate; +import org.elasticsearch.watcher.support.text.TextTemplateEngine; + +import java.util.Map; + +public class MockTextTemplateEngine implements TextTemplateEngine { + @Override + public String render(TextTemplate template, Map model) { + return template.getTemplate(); + } +} diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java index 619ecfed0f0..cab1885ad1b 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java @@ -56,8 +56,7 @@ import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy; import org.elasticsearch.watcher.support.secret.Secret; import org.elasticsearch.watcher.support.text.TextTemplate; import org.elasticsearch.watcher.support.text.TextTemplateEngine; -import org.elasticsearch.watcher.support.text.xmustache.XMustacheScriptEngineService; -import org.elasticsearch.watcher.support.text.xmustache.XMustacheTextTemplateEngine; +import org.elasticsearch.watcher.support.text.DefaultTextTemplateEngine; import org.elasticsearch.watcher.support.xcontent.ObjectPath; import org.elasticsearch.watcher.support.xcontent.XContentSource; import org.elasticsearch.watcher.transform.search.ExecutableSearchTransform; @@ -175,12 +174,12 @@ public final class WatcherTestUtils { } - public static Watch createTestWatch(String watchName, ScriptServiceProxy scriptService, HttpClient httpClient, EmailService emailService, ESLogger logger) throws AddressException { - return createTestWatch(watchName, ClientProxy.of(ESIntegTestCase.client()), scriptService, httpClient, emailService, logger); + public static Watch createTestWatch(String watchName, HttpClient httpClient, EmailService emailService, ESLogger logger) throws AddressException { + return createTestWatch(watchName, ClientProxy.of(ESIntegTestCase.client()), httpClient, emailService, logger); } - public static Watch createTestWatch(String watchName, ClientProxy client, ScriptServiceProxy scriptService, HttpClient httpClient, EmailService emailService, ESLogger logger) throws AddressException { + public static Watch createTestWatch(String watchName, ClientProxy client, HttpClient httpClient, EmailService emailService, ESLogger logger) throws AddressException { SearchRequest conditionRequest = newInputSearchRequest("my-condition-index").source(searchSource().query(matchAllQuery())); SearchRequest transformRequest = newInputSearchRequest("my-payload-index").source(searchSource().query(matchAllQuery())); @@ -197,7 +196,7 @@ public final class WatcherTestUtils { TextTemplate body = TextTemplate.inline("{{ctx.watch_id}} executed with {{ctx.payload.response.hits.total_hits}} hits").build(); httpRequest.body(body); - TextTemplateEngine engine = new XMustacheTextTemplateEngine(Settings.EMPTY, scriptService); + TextTemplateEngine engine = new MockTextTemplateEngine(); actions.add(new ActionWrapper("_webhook", new ExecutableWebhookAction(new WebhookAction(httpRequest.build()), logger, httpClient, engine))); @@ -209,12 +208,10 @@ public final class WatcherTestUtils { .to(to) .build(); - TextTemplateEngine templateEngine = new XMustacheTextTemplateEngine(Settings.EMPTY, scriptService); - Authentication auth = new Authentication("testname", new Secret("testpassword".toCharArray())); EmailAction action = new EmailAction(email, "testaccount", auth, Profile.STANDARD, null, null); - ExecutableEmailAction executale = new ExecutableEmailAction(action, logger, emailService, templateEngine, new HtmlSanitizer(Settings.EMPTY), Collections.emptyMap()); + ExecutableEmailAction executale = new ExecutableEmailAction(action, logger, emailService, engine, new HtmlSanitizer(Settings.EMPTY), Collections.emptyMap()); actions.add(new ActionWrapper("_email", executale)); @@ -246,15 +243,12 @@ public final class WatcherTestUtils { .put("script.indexed", "true") .put("path.home", createTempDir()) .build(); - XMustacheScriptEngineService mustacheScriptEngineService = new XMustacheScriptEngineService(settings); - Set engineServiceSet = new HashSet<>(); - engineServiceSet.add(mustacheScriptEngineService); ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Arrays.asList(ScriptServiceProxy.INSTANCE)); ScriptEngineRegistry scriptEngineRegistry = - new ScriptEngineRegistry(Collections.singletonList(new ScriptEngineRegistry.ScriptEngineRegistration(XMustacheScriptEngineService.class, XMustacheScriptEngineService.TYPES))); + new ScriptEngineRegistry(Collections.emptyList()); ScriptSettings scriptSettings = new ScriptSettings(scriptEngineRegistry, scriptContextRegistry); - return ScriptServiceProxy.of(new ScriptService(settings, new Environment(settings), engineServiceSet, new ResourceWatcherService(settings, tp), scriptEngineRegistry, scriptContextRegistry, scriptSettings)); + return ScriptServiceProxy.of(new ScriptService(settings, new Environment(settings), Collections.emptySet(), new ResourceWatcherService(settings, tp), scriptEngineRegistry, scriptContextRegistry, scriptSettings)); } public static SearchType getRandomSupportedSearchType() { diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/BasicWatcherTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/integration/BasicWatcherTests.java similarity index 81% rename from elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/BasicWatcherTests.java rename to elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/integration/BasicWatcherTests.java index 20293295178..b83100b7472 100644 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/BasicWatcherTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/integration/BasicWatcherTests.java @@ -3,7 +3,7 @@ * 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.messy.tests; +package org.elasticsearch.watcher.test.integration; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.action.search.SearchRequest; @@ -13,10 +13,8 @@ import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.Callback; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.plugins.Plugin; import org.elasticsearch.script.ScriptService.ScriptType; import org.elasticsearch.script.Template; -import org.elasticsearch.script.mustache.MustachePlugin; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.watcher.client.WatchSourceBuilder; import org.elasticsearch.watcher.client.WatcherClient; @@ -34,14 +32,9 @@ import org.elasticsearch.watcher.trigger.schedule.support.MonthTimes; import org.elasticsearch.watcher.trigger.schedule.support.WeekTimes; import org.elasticsearch.watcher.watch.WatchStore; -import java.util.ArrayList; -import java.util.List; - import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; -import static org.elasticsearch.index.query.QueryBuilders.boolQuery; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; -import static org.elasticsearch.index.query.QueryBuilders.rangeQuery; import static org.elasticsearch.index.query.QueryBuilders.termQuery; import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; @@ -56,6 +49,7 @@ import static org.elasticsearch.watcher.input.InputBuilders.simpleInput; import static org.elasticsearch.watcher.test.WatcherTestUtils.newInputSearchRequest; import static org.elasticsearch.watcher.test.WatcherTestUtils.xContentSource; import static org.elasticsearch.watcher.trigger.TriggerBuilders.schedule; +import static org.elasticsearch.watcher.trigger.schedule.Schedules.cron; import static org.elasticsearch.watcher.trigger.schedule.Schedules.daily; import static org.elasticsearch.watcher.trigger.schedule.Schedules.hourly; import static org.elasticsearch.watcher.trigger.schedule.Schedules.interval; @@ -70,13 +64,10 @@ import static org.hamcrest.Matchers.notNullValue; public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase { @Override - protected List> pluginTypes() { - List> types = new ArrayList<>(); - types.addAll(super.pluginTypes()); - types.add(MustachePlugin.class); - return types; + protected boolean timeWarped() { + return true; } - + public void testIndexWatch() throws Exception { WatcherClient watcherClient = watcherClient(); createIndex("idx"); @@ -89,17 +80,10 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase { .trigger(schedule(interval(5, IntervalSchedule.Interval.Unit.SECONDS))) .input(searchInput(searchRequest)) .condition(compareCondition("ctx.payload.hits.total", CompareCondition.Op.EQ, 1L)) - .addAction("_logger", loggingAction("\n\n************\n" + - "total hits: {{ctx.payload.hits.total}}\n" + - "************\n") + .addAction("_logger", loggingAction("_logging") .setCategory("_category"))) .get(); - - if (timeWarped()) { - timeWarp().scheduler().trigger("_name"); - refresh(); - } - + timeWarp().scheduler().trigger("_name"); assertWatchWithMinimumPerformedActionsCount("_name", 1); GetWatchResponse getWatchResponse = watcherClient().prepareGetWatch().setId("_name").get(); @@ -116,12 +100,7 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase { .input(searchInput(searchRequest)) .condition(compareCondition("ctx.payload.hits.total", CompareCondition.Op.EQ, 1L))) .get(); - - if (timeWarped()) { - timeWarp().scheduler().trigger("_name"); - refresh(); - } - + timeWarp().scheduler().trigger("_name"); // The watch's condition won't meet because there is no data that matches with the query assertWatchWithNoActionNeeded("_name", 1); @@ -143,20 +122,11 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase { SearchRequest searchRequest = newInputSearchRequest("idx").source(searchSource().query(matchAllQuery())); PutWatchResponse indexResponse = watcherClient.preparePutWatch("_name") .setSource(watchBuilder() - .trigger(schedule(interval(5, IntervalSchedule.Interval.Unit.SECONDS))) + .trigger(schedule(cron("0/1 * * * * ? 2020"))) .input(searchInput(searchRequest)) .condition(compareCondition("ctx.payload.hits.total", CompareCondition.Op.EQ, 1L))) .get(); assertThat(indexResponse.isCreated(), is(true)); - - if (!timeWarped()) { - // Although there is no added benefit in this test for waiting for the watch to fire, however - // we need to wait here because of a test timing issue. When we tear down a test we delete the watch and delete all - // indices, but there may still be inflight fired watches, which may trigger the watch history to be created again, before - // we finished the tear down phase. - assertWatchWithNoActionNeeded("_name", 1); - } - DeleteWatchResponse deleteWatchResponse = watcherClient.prepareDeleteWatch("_name").get(); assertThat(deleteWatchResponse, notNullValue()); assertThat(deleteWatchResponse.isFound(), is(true)); @@ -217,22 +187,17 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase { .setSource(source.condition(compareCondition("ctx.payload.hits.total", CompareCondition.Op.EQ, 1L))) .get(); - if (timeWarped()) { - timeWarp().clock().fastForwardSeconds(5); - timeWarp().scheduler().trigger("_name"); - refresh(); - } + timeWarp().clock().fastForwardSeconds(5); + timeWarp().scheduler().trigger("_name"); assertWatchWithMinimumPerformedActionsCount("_name", 0, false); watcherClient().preparePutWatch("_name") .setSource(source.condition(compareCondition("ctx.payload.hits.total", CompareCondition.Op.EQ, 0L))) .get(); - if (timeWarped()) { - timeWarp().clock().fastForwardSeconds(5); - timeWarp().scheduler().trigger("_name"); - refresh(); - } + timeWarp().clock().fastForwardSeconds(5); + timeWarp().scheduler().trigger("_name"); + refresh(); assertWatchWithMinimumPerformedActionsCount("_name", 1, false); watcherClient().preparePutWatch("_name") @@ -241,24 +206,12 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase { .condition(compareCondition("ctx.payload.hits.total", CompareCondition.Op.EQ, 0L))) .get(); - if (timeWarped()) { - timeWarp().clock().fastForwardSeconds(5); - timeWarp().scheduler().trigger("_name"); - refresh(); - } else { - Thread.sleep(1000); - } - + timeWarp().clock().fastForwardSeconds(5); + timeWarp().scheduler().trigger("_name"); long count = findNumberOfPerformedActions("_name"); - if (timeWarped()) { - timeWarp().clock().fastForwardSeconds(5); - timeWarp().scheduler().trigger("_name"); - refresh(); - } else { - Thread.sleep(1000); - } - + timeWarp().clock().fastForwardSeconds(5); + timeWarp().scheduler().trigger("_name"); assertThat(count, equalTo(findNumberOfPerformedActions("_name"))); } @@ -272,7 +225,7 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase { .trigger(schedule(interval("1s"))) .input(simpleInput("key", "value")) .defaultThrottlePeriod(TimeValue.timeValueSeconds(0)) - .addAction("_id", loggingAction("hello {{ctx.watcher_id}}!")); + .addAction("_id", loggingAction("_logging")); watcherClient().preparePutWatch("_name") .setSource(source) .get(); @@ -284,7 +237,7 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase { .trigger(schedule(interval("100s"))) .defaultThrottlePeriod(TimeValue.timeValueSeconds(0)) .input(simpleInput("key", "value")) - .addAction("_id", loggingAction("hello {{ctx.watcher_id}}!")); + .addAction("_id", loggingAction("_logging")); watcherClient().preparePutWatch("_name") .setSource(source) .get(); @@ -297,24 +250,12 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase { } public void testConditionSearchWithSource() throws Exception { - String variable = randomFrom("ctx.execution_time", "ctx.trigger.scheduled_time", "ctx.trigger.triggered_time"); - SearchSourceBuilder searchSourceBuilder = searchSource().query(boolQuery() - .must(matchQuery("level", "a")) - .must(rangeQuery("_timestamp") - .from("{{" + variable + "}}||-30s") - .to("{{" + variable + "}}"))); - + SearchSourceBuilder searchSourceBuilder = searchSource().query(matchQuery("level", "a")); testConditionSearch(newInputSearchRequest("events").source(searchSourceBuilder)); } public void testConditionSearchWithIndexedTemplate() throws Exception { - String variable = randomFrom("ctx.execution_time", "ctx.trigger.scheduled_time", "ctx.trigger.triggered_time"); - SearchSourceBuilder searchSourceBuilder = searchSource().query(boolQuery() - .must(matchQuery("level", "a")) - .must(rangeQuery("_timestamp") - .from("{{" + variable + "}}||-30s") - .to("{{" + variable + "}}"))); - + SearchSourceBuilder searchSourceBuilder = searchSource().query(matchQuery("level", "a")); client().preparePutIndexedScript() .setScriptLang("mustache") .setId("my-template") @@ -350,14 +291,8 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase { .condition(compareCondition("ctx.payload.hits.max_score", CompareCondition.Op.GTE, 0L))) .get(); - if (timeWarped()) { - timeWarp().scheduler().trigger("_name1"); - timeWarp().scheduler().trigger("_name2"); - refresh(); - } else { - Thread.sleep(5000); - } - + timeWarp().scheduler().trigger("_name1"); + timeWarp().scheduler().trigger("_name2"); assertWatchWithMinimumPerformedActionsCount("_name1", 1); assertWatchWithNoActionNeeded("_name2", 1); @@ -442,10 +377,8 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase { } private void testConditionSearch(SearchRequest request) throws Exception { - if (timeWarped()) { - // reset, so we don't miss event docs when we filter over the _timestamp field. - timeWarp().clock().setTime(SystemClock.INSTANCE.nowUTC()); - } + // reset, so we don't miss event docs when we filter over the _timestamp field. + timeWarp().clock().setTime(SystemClock.INSTANCE.nowUTC()); String watchName = "_name"; assertAcked(prepareCreate("events").addMapping("event", "_timestamp", "enabled=true", "level", "type=string")); @@ -469,14 +402,7 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase { .get(); refresh(); - - if (timeWarped()) { - timeWarp().clock().fastForwardSeconds(5); - timeWarp().scheduler().trigger(watchName); - refresh(); - } else { - Thread.sleep(5000); - } + timeWarp().scheduler().trigger(watchName); assertWatchWithNoActionNeeded(watchName, 1); client().prepareIndex("events", "event") @@ -484,13 +410,7 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase { .setSource("level", "b") .get(); refresh(); - if (timeWarped()) { - timeWarp().clock().fastForwardSeconds(5); - timeWarp().scheduler().trigger(watchName); - refresh(); - } else { - Thread.sleep(5000); - } + timeWarp().scheduler().trigger(watchName); assertWatchWithNoActionNeeded(watchName, 2); client().prepareIndex("events", "event") @@ -498,13 +418,7 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase { .setSource("level", "a") .get(); refresh(); - if (timeWarped()) { - timeWarp().clock().fastForwardSeconds(5); - timeWarp().scheduler().trigger(watchName); - refresh(); - } else { - Thread.sleep(5000); - } + timeWarp().scheduler().trigger(watchName); assertWatchWithMinimumPerformedActionsCount(watchName, 1); } } diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/integration/WatchMetadataTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/integration/WatchMetadataTests.java index 2fb36bcf883..be15020dc4c 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/integration/WatchMetadataTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/integration/WatchMetadataTests.java @@ -81,7 +81,7 @@ public class WatchMetadataTests extends AbstractWatcherIntegrationTestCase { metadata.put("foo", "bar"); metadata.put("logtext", "This is a test"); - LoggingAction.Builder loggingAction = loggingAction(TextTemplate.inline("{{ctx.metadata.logtext}}")) + LoggingAction.Builder loggingAction = loggingAction(TextTemplate.inline("_logging")) .setLevel(LoggingLevel.DEBUG) .setCategory("test"); @@ -102,6 +102,6 @@ public class WatchMetadataTests extends AbstractWatcherIntegrationTestCase { assertThat(ObjectPath.eval("metadata.foo", result), equalTo("bar")); assertThat(ObjectPath.eval("result.actions.0.id", result), equalTo("testLogger")); - assertThat(ObjectPath.eval("result.actions.0.logging.logged_text", result), equalTo("This is a test")); + assertThat(ObjectPath.eval("result.actions.0.logging.logged_text", result), equalTo("_logging")); } }