From 01c80e63b0c2501a384661db9237b83fb012cecc Mon Sep 17 00:00:00 2001 From: Brian Murphy Date: Mon, 27 Apr 2015 09:33:23 -0400 Subject: [PATCH] [TEST] Add automated tests that were missing. SearchInput using inline, indexed and on disk templates. ScriptedCondition where the script accesses the ctx. ScriptedCondition where the script throws an exception. ScriptedCondition where the script doesn't return a boolean. Webhook tests using templated body, path and parameters. Some REST test fixes. Original commit: elastic/x-pack-elasticsearch@d02b6d1d7bd8210768b1f6df94b9f146fe9ee154 --- rest-api-spec/test/ack_watch/10_basic.yaml | 4 +- rest-api-spec/test/delete_watch/10_basic.yaml | 4 +- .../test/execute_watch/10_basic.yaml | 2 +- .../test/execute_watch/20_empty_body.yaml | 3 +- rest-api-spec/test/get_watch/10_basic.yaml | 4 +- rest-api-spec/test/put_watch/10_basic.yaml | 4 +- .../script/ExecutableScriptCondition.java | 16 +- .../input/search/ExecutableSearchInput.java | 16 +- .../watcher/support/WatcherUtils.java | 4 + .../actions/webhook/WebhookActionTests.java | 72 +++++++-- .../script/ScriptConditionTests.java | 34 +++++ .../input/search/SearchInputTests.java | 140 +++++++++++++++++- .../scripts/test_disk_template.mustache | 24 +++ 13 files changed, 289 insertions(+), 38 deletions(-) create mode 100644 src/test/resources/org/elasticsearch/watcher/input/search/config/scripts/test_disk_template.mustache diff --git a/rest-api-spec/test/ack_watch/10_basic.yaml b/rest-api-spec/test/ack_watch/10_basic.yaml index af4f3254c83..5080824ed27 100644 --- a/rest-api-spec/test/ack_watch/10_basic.yaml +++ b/rest-api-spec/test/ack_watch/10_basic.yaml @@ -24,14 +24,14 @@ } }, "condition": { - "always_true": {} + "always": {} }, "actions": [ { "test_index": { "index": { "index": "test", - "type": "test2" + "doc_type": "test2" } } } ] diff --git a/rest-api-spec/test/delete_watch/10_basic.yaml b/rest-api-spec/test/delete_watch/10_basic.yaml index 05fda3116b6..77cf30dd0ff 100644 --- a/rest-api-spec/test/delete_watch/10_basic.yaml +++ b/rest-api-spec/test/delete_watch/10_basic.yaml @@ -24,14 +24,14 @@ } }, "condition": { - "always_true": {} + "always": {} }, "actions": [ { "test_index": { "index": { "index": "test", - "type": "test2" + "doc_type": "test2" } } } ] diff --git a/rest-api-spec/test/execute_watch/10_basic.yaml b/rest-api-spec/test/execute_watch/10_basic.yaml index 3a34151845b..6e26bd4fedd 100644 --- a/rest-api-spec/test/execute_watch/10_basic.yaml +++ b/rest-api-spec/test/execute_watch/10_basic.yaml @@ -71,7 +71,7 @@ "record_execution" : true } - match: { "watch_id": "my_exe_watch" } - - match: { "watch_execution.condition_result.always_true": {} } + - match: { "watch_execution.condition_result.always": {} } - match: { "state": "executed" } - match: { "trigger_event.manual.trigger_data.scheduled_time": "now" } - match: { "watch_execution.input_result.simple.payload.foo": "bar" } diff --git a/rest-api-spec/test/execute_watch/20_empty_body.yaml b/rest-api-spec/test/execute_watch/20_empty_body.yaml index 9ddf5e1145e..7dc8a3b2064 100644 --- a/rest-api-spec/test/execute_watch/20_empty_body.yaml +++ b/rest-api-spec/test/execute_watch/20_empty_body.yaml @@ -15,7 +15,6 @@ "input" : { "search" : { "request" : { - "indices" : [ "logstash*" ], "body" : { "query" : { "filtered": { @@ -59,7 +58,7 @@ body: null - match: { "watch_id": "my_logging_watch" } - - match: { "watch_execution.condition_result.always_true": {} } + - match: { "watch_execution.condition_result.always": {} } - match: { "state": "executed" } - match: { "watch_execution.actions_results.Logging.logging.success" : true } - match: { "watch_execution.actions_results.Logging.logging.logged_text" : "foobar" } diff --git a/rest-api-spec/test/get_watch/10_basic.yaml b/rest-api-spec/test/get_watch/10_basic.yaml index af39b55f5bf..3533ef6cf35 100644 --- a/rest-api-spec/test/get_watch/10_basic.yaml +++ b/rest-api-spec/test/get_watch/10_basic.yaml @@ -24,14 +24,14 @@ } }, "condition": { - "always_true": {} + "always": {} }, "actions": [ { "test_index": { "index": { "index": "test", - "type": "test2" + "doc_type": "test2" } } } diff --git a/rest-api-spec/test/put_watch/10_basic.yaml b/rest-api-spec/test/put_watch/10_basic.yaml index efe7e0d9537..c95120ba5b4 100644 --- a/rest-api-spec/test/put_watch/10_basic.yaml +++ b/rest-api-spec/test/put_watch/10_basic.yaml @@ -24,14 +24,14 @@ } }, "condition": { - "always_true": {} + "always": {} }, "actions": [ { "test_index": { "index": { "index": "test", - "type": "test2" + "doc_type": "test2" } } } ] diff --git a/src/main/java/org/elasticsearch/watcher/condition/script/ExecutableScriptCondition.java b/src/main/java/org/elasticsearch/watcher/condition/script/ExecutableScriptCondition.java index faa388a8ea0..a0ec9483c45 100644 --- a/src/main/java/org/elasticsearch/watcher/condition/script/ExecutableScriptCondition.java +++ b/src/main/java/org/elasticsearch/watcher/condition/script/ExecutableScriptCondition.java @@ -7,7 +7,7 @@ package org.elasticsearch.watcher.condition.script; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.script.ExecutableScript; -import org.elasticsearch.watcher.condition.ConditionException; +import org.elasticsearch.script.groovy.GroovyScriptExecutionException; import org.elasticsearch.watcher.condition.ExecutableCondition; import org.elasticsearch.watcher.execution.WatchExecutionContext; import org.elasticsearch.watcher.support.Variables; @@ -29,11 +29,15 @@ public class ExecutableScriptCondition extends ExecutableCondition templateParams = Variables.createCtxModel(ctx, null); + templateParams.putAll(requestPrototype.templateParams()); + if (Strings.hasLength(requestPrototype.source())) { - Map templateParams = Variables.createCtxModel(ctx, null); String requestSource = XContentHelper.convertToJson(requestPrototype.source(), false); ExecutableScript script = scriptService.executable("mustache", requestSource, ScriptService.ScriptType.INLINE, templateParams); request.source((BytesReference) script.unwrap(script.run()), false); + } else if (Strings.hasLength(requestPrototype.templateSource())) { + String requestSource = XContentHelper.convertToJson(requestPrototype.templateSource(), false); + ExecutableScript script = scriptService.executable("mustache", requestSource, ScriptService.ScriptType.INLINE, templateParams); + request.source((BytesReference) script.unwrap(script.run()), false); } else if (requestPrototype.templateName() != null) { - Map templateParams = Variables.createCtxModel(ctx, null); - templateParams.putAll(requestPrototype.templateParams()); + //templateParams = WatcherUtils.flattenModel(templateParams); request.templateParams(templateParams); request.templateName(requestPrototype.templateName()); request.templateType(requestPrototype.templateType()); - } + } /*else { + request.templateParams(templateParams); + }*/ // falling back to an empty body return request; } diff --git a/src/main/java/org/elasticsearch/watcher/support/WatcherUtils.java b/src/main/java/org/elasticsearch/watcher/support/WatcherUtils.java index b4e08dcb508..c4cf48958f3 100644 --- a/src/main/java/org/elasticsearch/watcher/support/WatcherUtils.java +++ b/src/main/java/org/elasticsearch/watcher/support/WatcherUtils.java @@ -254,6 +254,10 @@ public final class WatcherUtils { } private static void flattenModel(String key, Object value, Map result) { + if (value == null) { + result.put(key, null); + return; + } if (value instanceof Map) { for (Map.Entry entry : ((Map) value).entrySet()) { if ("".equals(key)) { diff --git a/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookActionTests.java b/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookActionTests.java index 32067c304f0..1af851f85a9 100644 --- a/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookActionTests.java +++ b/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookActionTests.java @@ -49,18 +49,22 @@ import org.junit.Test; import javax.mail.internet.AddressException; import java.io.IOException; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; +import static org.elasticsearch.common.joda.time.DateTimeZone.UTC; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.Matchers.greaterThanOrEqualTo; -import static org.hamcrest.Matchers.lessThanOrEqualTo; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.Matchers.*; import static org.hamcrest.core.Is.is; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; + /** */ public class WebhookActionTests extends ElasticsearchTestCase { @@ -108,7 +112,7 @@ public class WebhookActionTests extends ElasticsearchTestCase { final String account = "account1"; - HttpRequestTemplate httpRequest = getHttpRequestTemplate(method, TEST_HOST, TEST_PORT, testPath, testBody); + HttpRequestTemplate httpRequest = getHttpRequestTemplate(method, TEST_HOST, TEST_PORT, testPath, testBody, null); WebhookAction action = new WebhookAction(httpRequest); ExecutableWebhookAction executable = new ExecutableWebhookAction(action, logger, httpClient, templateEngine); @@ -120,7 +124,7 @@ public class WebhookActionTests extends ElasticsearchTestCase { scenario.assertResult(actionResult); } - private HttpRequestTemplate getHttpRequestTemplate(HttpMethod method, String host, int port, Template path, Template body) { + private HttpRequestTemplate getHttpRequestTemplate(HttpMethod method, String host, int port, Template path, Template body, Map params) { HttpRequestTemplate.Builder builder = HttpRequestTemplate.builder(host, port); if (path != null) { builder.path(path); @@ -131,6 +135,9 @@ public class WebhookActionTests extends ElasticsearchTestCase { if (method != null) { builder.method(method); } + if (params != null){ + builder.putParams(params); + } return builder.build(); } @@ -140,7 +147,7 @@ public class WebhookActionTests extends ElasticsearchTestCase { Template path = new Template("_url"); String host = "test.host"; HttpMethod method = randomFrom(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, null); - HttpRequestTemplate request = getHttpRequestTemplate(method, host, TEST_PORT, path, body); + HttpRequestTemplate request = getHttpRequestTemplate(method, host, TEST_PORT, path, body, null); XContentBuilder builder = jsonBuilder(); request.toXContent(builder, Attachment.XContent.EMPTY_PARAMS); @@ -165,7 +172,7 @@ public class WebhookActionTests extends ElasticsearchTestCase { HttpMethod method = randomFrom(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, null); - HttpRequestTemplate request = getHttpRequestTemplate(method, host, TEST_PORT, path, body); + HttpRequestTemplate request = getHttpRequestTemplate(method, host, TEST_PORT, path, body, null); WebhookAction action = new WebhookAction(request); ExecutableWebhookAction executable = new ExecutableWebhookAction(action, logger, ExecuteScenario.Success.client(), templateEngine); @@ -192,7 +199,7 @@ public class WebhookActionTests extends ElasticsearchTestCase { String actionId = randomAsciiOfLength(5); HttpMethod method = randomFrom(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, null); - HttpRequestTemplate request = getHttpRequestTemplate(method, host, TEST_PORT, path, body); + HttpRequestTemplate request = getHttpRequestTemplate(method, host, TEST_PORT, path, body, null); WebhookAction action = WebhookAction.builder(request).build(); @@ -348,6 +355,42 @@ public class WebhookActionTests extends ElasticsearchTestCase { new HttpRequestTemplate.Parser(authRegistry), templateEngine); } + @Test + @Repeat(iterations = 10) + 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", new Template(randomFrom("{{ctx.execution_time}}", "{{ctx.trigger.scheduled_time}}", "{{ctx.trigger.triggered_time}}"))); + HttpMethod method = randomFrom(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT); + + HttpRequestTemplate request = getHttpRequestTemplate(method, host, TEST_PORT, new Template(path), new Template(body), 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)); + WebhookAction.Result result = webhookAction.doExecute(actionId, ctx, Payload.EMPTY); + + assertThat(result, Matchers.instanceOf(WebhookAction.Result.Executed.class)); + WebhookAction.Result.Executed executed = (WebhookAction.Result.Executed) result; + assertThat(executed.request().body(), equalTo(watchId)); + assertThat(executed.request().path(), equalTo(time.toString())); + assertThat(executed.request().params().get("foo"), equalTo(time.toString())); + + } + @Test @Repeat(iterations = 100) public void testValidUrls() throws Exception { @@ -355,20 +398,20 @@ public class WebhookActionTests extends ElasticsearchTestCase { HttpMethod method = HttpMethod.POST; Template path = new Template("/test_{{ctx.watch_id}}"); String host = "test.host"; - HttpRequestTemplate requestTemplate = getHttpRequestTemplate(method, host, TEST_PORT, path, testBody); + HttpRequestTemplate requestTemplate = getHttpRequestTemplate(method, host, TEST_PORT, path, testBody, null); WebhookAction action = new WebhookAction(requestTemplate); ExecutableWebhookAction webhookAction = new ExecutableWebhookAction(action, logger, httpClient, templateEngine); - String watchName = "test_url_encode" + randomAsciiOfLength(10); - Watch watch = createWatch(watchName, mock(ClientProxy.class), "account1"); - WatchExecutionContext ctx = new TriggeredExecutionContext(watch, new DateTime(), new ScheduleTriggerEvent(watchName, new DateTime(), new DateTime())); + 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))); WebhookAction.Result result = webhookAction.execute("_id", ctx, new Payload.Simple()); assertThat(result, Matchers.instanceOf(WebhookAction.Result.Executed.class)); } - private Watch createWatch(String watchName, ClientProxy client, final String account) throws AddressException, IOException { - return WatcherTestUtils.createTestWatch(watchName, + private Watch createWatch(String watchId, ClientProxy client, final String account) throws AddressException, IOException { + return WatcherTestUtils.createTestWatch(watchId, client, scriptService, ExecuteScenario.Success.client(), @@ -449,7 +492,6 @@ public class WebhookActionTests extends ElasticsearchTestCase { public abstract HttpClient client() throws IOException; public abstract void assertResult(WebhookAction.Result result); - } } diff --git a/src/test/java/org/elasticsearch/watcher/condition/script/ScriptConditionTests.java b/src/test/java/org/elasticsearch/watcher/condition/script/ScriptConditionTests.java index 492a755af36..f14297cda02 100644 --- a/src/test/java/org/elasticsearch/watcher/condition/script/ScriptConditionTests.java +++ b/src/test/java/org/elasticsearch/watcher/condition/script/ScriptConditionTests.java @@ -9,6 +9,7 @@ import com.carrotsearch.randomizedtesting.annotations.Repeat; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.common.collect.ImmutableMap; +import org.elasticsearch.common.joda.time.DateTime; import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -36,8 +37,10 @@ import java.io.IOException; import java.util.HashSet; import java.util.Set; +import static org.elasticsearch.common.joda.time.DateTimeZone.UTC; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.watcher.test.WatcherTestUtils.mockExecutionContext; +import static org.hamcrest.Matchers.is; /** */ @@ -162,6 +165,37 @@ public class ScriptConditionTests extends ElasticsearchTestCase { fail("expected a condition exception trying to parse an invalid condition XContent"); } + @Test(expected = ScriptConditionException.class) + public void testScriptCondition_throwException() throws Exception { + ScriptServiceProxy scriptService = getScriptServiceProxy(tp); + ExecutableScriptCondition condition = new ExecutableScriptCondition(new ScriptCondition(new Script("assert false")), logger, scriptService); + SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500l, new ShardSearchFailure[0]); + WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response)); + condition.execute(ctx); + fail(); + } + + @Test(expected = ScriptConditionException.class) + public void testScriptCondition_returnObject() throws Exception { + ScriptServiceProxy scriptService = getScriptServiceProxy(tp); + ExecutableScriptCondition condition = new ExecutableScriptCondition(new ScriptCondition(new Script("return new Object()")), logger, scriptService); + SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500l, new ShardSearchFailure[0]); + WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response)); + condition.execute(ctx); + fail(); + } + + @Test + public void testScriptCondition_accessCtx() throws Exception { + ScriptServiceProxy scriptService = getScriptServiceProxy(tp); + ExecutableScriptCondition condition = new ExecutableScriptCondition(new ScriptCondition(new Script("ctx.trigger.scheduled_time.getMillis() < System.currentTimeMillis() ")), logger, scriptService); + SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500l, new ShardSearchFailure[0]); + WatchExecutionContext ctx = mockExecutionContext("_name", new DateTime(UTC), new Payload.XContent(response)); + Thread.sleep(10); + assertThat(condition.execute(ctx).met(), is(true)); + } + + private static ScriptServiceProxy getScriptServiceProxy(ThreadPool tp) throws IOException { Settings settings = ImmutableSettings.settingsBuilder() .put(ScriptService.DISABLE_DYNAMIC_SCRIPTING_SETTING, "none") diff --git a/src/test/java/org/elasticsearch/watcher/input/search/SearchInputTests.java b/src/test/java/org/elasticsearch/watcher/input/search/SearchInputTests.java index adb2c4a4bd1..22fd61e72a8 100644 --- a/src/test/java/org/elasticsearch/watcher/input/search/SearchInputTests.java +++ b/src/test/java/org/elasticsearch/watcher/input/search/SearchInputTests.java @@ -5,10 +5,13 @@ */ package org.elasticsearch.watcher.input.search; +import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptRequest; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchType; import org.elasticsearch.common.joda.time.DateTime; import org.elasticsearch.common.settings.ImmutableSettings; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; @@ -36,18 +39,21 @@ import org.elasticsearch.watcher.watch.Payload; import org.elasticsearch.watcher.watch.Watch; import org.junit.Test; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.elasticsearch.common.joda.time.DateTimeZone.UTC; +import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.index.query.FilterBuilders.rangeFilter; import static org.elasticsearch.index.query.QueryBuilders.filteredQuery; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; import static org.mockito.Mockito.mock; @@ -55,6 +61,41 @@ import static org.mockito.Mockito.mock; */ public class SearchInputTests extends ElasticsearchIntegrationTest { + private final static String TEMPLATE_QUERY = "{\"query\":{\"filtered\":{\"query\":{\"match\":{\"event_type\":{\"query\":\"a\"," + + "\"type\":\"boolean\"}}},\"filter\":{\"range\":{\"_timestamp\":" + + "{\"from\":\"{{ctx.trigger.scheduled_time}}||-{{seconds_param}}\",\"to\":\"{{ctx.trigger.scheduled_time}}\"," + + "\"include_lower\":true,\"include_upper\":true}}}}}}"; + + private final static String EXPECTED_TEMPLATE_QUERY = "{\"query\":{\"filtered\":{\"query\":{\"match\":{\"event_type\":" + + "{\"query\":\"a\",\"type\":\"boolean\"}}},\"filter\":{\"range\":{\"_timestamp\":{\"from\":\"1970-01-01T00:01:00.000Z||-30s\"," + + "\"to\":\"1970-01-01T00:01:00.000Z\",\"include_lower\":true,\"include_upper\":true}}}}}}"; + + + @Override + public Settings nodeSettings(int nodeOrdinal) { + //Set path so ScriptService will pick up the test scripts + return settingsBuilder().put(super.nodeSettings(nodeOrdinal)) + .put("path.conf", this.getResource("config").getPath()).build(); + } + + + + private IndexResponse indexTestDoc() { + createIndex("test-search-index"); + ensureGreen("test-search-index"); + + IndexResponse response = client().index( + client().prepareIndex() + .setId("test") + .setIndex("test-search-index") + .setType("test-search-type") + .setSource("foo","bar") + .setTimestamp(new DateTime(40000, UTC).toString()).request()).actionGet(); + assertThat(response.isCreated(), is(true)); + refresh(); + return response; + } + @Test public void testExecute() throws Exception { SearchSourceBuilder searchSourceBuilder = searchSource().query( @@ -91,6 +132,72 @@ public class SearchInputTests extends ElasticsearchIntegrationTest { assertEquals(result.executedRequest().indicesOptions(), request.indicesOptions()); } + @Test + public void testSearch_InlineTemplate() throws Exception { + + ScriptService.ScriptType scriptType = ScriptService.ScriptType.INLINE; + + Map params = new HashMap<>(); + params.put("seconds_param", "30s"); + + SearchRequest request = client() + .prepareSearch() + .setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE) + .setIndices("test-search-index") + .setTemplateSource(TEMPLATE_QUERY) + .setTemplateParams(params) + .setTemplateType(scriptType) + .request(); + + + SearchInput.Result executedResult = executeSearchInput(request); + + assertThat(executedResult.executedRequest().source().toUtf8(), equalTo(EXPECTED_TEMPLATE_QUERY)); + } + + @Test + public void testSearch_IndexedTemplate() throws Exception { + PutIndexedScriptRequest indexedScriptRequest = client().preparePutIndexedScript("mustache","test-script", TEMPLATE_QUERY).request(); + assertThat(client().putIndexedScript(indexedScriptRequest).actionGet().isCreated(), is(true)); + + ScriptService.ScriptType scriptType = ScriptService.ScriptType.INDEXED; + + Map params = new HashMap<>(); + params.put("seconds_param", "30s"); + + SearchRequest request = client() + .prepareSearch() + .setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE) + .setIndices("test-search-index") + .setTemplateName("test-script") + .setTemplateParams(params) + .setTemplateType(scriptType) + .request(); + + executeSearchInput(request); + //This will fail if templating fails + } + + @Test + public void testSearch_OndiskTemplate() throws Exception { + ScriptService.ScriptType scriptType = ScriptService.ScriptType.FILE; + + Map params = new HashMap<>(); + params.put("seconds_param", "30s"); + + SearchRequest request = client() + .prepareSearch() + .setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE) + .setIndices("test-search-index") + .setTemplateName("test_disk_template") + .setTemplateParams(params) + .setTemplateType(scriptType) + .request(); + + executeSearchInput(request).executedRequest(); + } + + @Test public void testDifferentSearchType() throws Exception { SearchSourceBuilder searchSourceBuilder = searchSource().query( @@ -151,7 +258,7 @@ public class SearchInputTests extends ElasticsearchIntegrationTest { @Test(expected = SearchInputException.class) public void testParser_Invalid() throws Exception { - SearchInputFactory factory = new SearchInputFactory(ImmutableSettings.settingsBuilder().build(), + SearchInputFactory factory = new SearchInputFactory(settingsBuilder().build(), ScriptServiceProxy.of(internalCluster().getInstance(ScriptService.class)), ClientProxy.of(client())); @@ -191,7 +298,7 @@ public class SearchInputTests extends ElasticsearchIntegrationTest { WatcherUtils.writeSearchRequest(request, jsonBuilder, ToXContent.EMPTY_PARAMS); jsonBuilder.endObject(); - SearchInputFactory factory = new SearchInputFactory(ImmutableSettings.settingsBuilder().build(), + SearchInputFactory factory = new SearchInputFactory(settingsBuilder().build(), ScriptServiceProxy.of(internalCluster().getInstance(ScriptService.class)), ClientProxy.of(client())); @@ -205,4 +312,33 @@ public class SearchInputTests extends ElasticsearchIntegrationTest { assertTrue(baz.isEmpty()); assertNotNull(result.executedRequest()); } + + private SearchInput.Result executeSearchInput(SearchRequest request) throws IOException { + + createIndex("test-search-index"); + ensureGreen("test-search-index"); + SearchInput.Builder siBuilder = SearchInput.builder(request); + + SearchInput si = siBuilder.build(); + + ExecutableSearchInput searchInput = new ExecutableSearchInput(si, logger, + ScriptServiceProxy.of(internalCluster().getInstance(ScriptService.class)), + ClientProxy.of(client())); + WatchExecutionContext ctx = new TriggeredExecutionContext( + new Watch("test-watch", + new ClockMock(), + mock(LicenseService.class), + new ScheduleTrigger(new IntervalSchedule(new IntervalSchedule.Interval(1, IntervalSchedule.Interval.Unit.MINUTES))), + new ExecutableSimpleInput(new SimpleInput(new Payload.Simple()), logger), + new ExecutableAlwaysCondition(logger), + null, + new ExecutableActions(new ArrayList()), + null, + null, + new Watch.Status()), + new DateTime(60000, UTC), + new ScheduleTriggerEvent("test-watch", new DateTime(60000, UTC), new DateTime(60000, UTC))); + return searchInput.execute(ctx); + } + } diff --git a/src/test/resources/org/elasticsearch/watcher/input/search/config/scripts/test_disk_template.mustache b/src/test/resources/org/elasticsearch/watcher/input/search/config/scripts/test_disk_template.mustache new file mode 100644 index 00000000000..822b9146255 --- /dev/null +++ b/src/test/resources/org/elasticsearch/watcher/input/search/config/scripts/test_disk_template.mustache @@ -0,0 +1,24 @@ +{ + "query": { + "filtered": { + "query": { + "match": { + "event_type": { + "query": "a", + "type": "boolean" + } + } + }, + "filter": { + "range": { + "_timestamp": { + "from": "{{ctx.trigger.scheduled_time}}||-{{seconds_param}}", + "to": "{{ctx.trigger.scheduled_time}}", + "include_lower": true, + "include_upper": true + } + } + } + } + } +} \ No newline at end of file