Watcher: Replace integration tests with unit and REST tests (elastic/x-pack-elasticsearch#2322)
A bunch of integration tests should have been built as unit tests or already have unit test equivalents. This commit removes integration tests as well as adding REST equivalents or creating unit tests instead of extending from AbstractWatcherIntegrationTestCase Original commit: elastic/x-pack-elasticsearch@a97b99467d
This commit is contained in:
parent
17de601e21
commit
4ac13fa9c5
|
@ -22,7 +22,7 @@ public class ExecutableLoggingAction extends ExecutableAction<LoggingAction> {
|
|||
private final Logger textLogger;
|
||||
private final TextTemplateEngine templateEngine;
|
||||
|
||||
ExecutableLoggingAction(LoggingAction action, Logger logger, Settings settings, TextTemplateEngine templateEngine) {
|
||||
public ExecutableLoggingAction(LoggingAction action, Logger logger, Settings settings, TextTemplateEngine templateEngine) {
|
||||
super(action, logger);
|
||||
this.textLogger = action.category != null ? Loggers.getLogger(action.category, settings) : logger;
|
||||
this.templateEngine = templateEngine;
|
||||
|
|
|
@ -28,6 +28,5 @@ public class LoggingActionFactory extends ActionFactory {
|
|||
public ExecutableLoggingAction parseExecutable(String watchId, String actionId, XContentParser parser) throws IOException {
|
||||
LoggingAction action = LoggingAction.parse(watchId, actionId, parser);
|
||||
return new ExecutableLoggingAction(action, actionLogger, settings, templateEngine);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,118 +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.xpack.watcher.condition;
|
||||
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.action.search.ShardSearchFailure;
|
||||
import org.elasticsearch.common.text.Text;
|
||||
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.script.MockScriptPlugin;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
import org.elasticsearch.search.SearchHits;
|
||||
import org.elasticsearch.search.SearchShardTarget;
|
||||
import org.elasticsearch.search.aggregations.AggregationBuilders;
|
||||
import org.elasticsearch.search.aggregations.BucketOrder;
|
||||
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
|
||||
import org.elasticsearch.search.internal.InternalSearchResponse;
|
||||
import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext;
|
||||
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
||||
import org.elasticsearch.xpack.watcher.watch.Payload;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.mockExecutionContext;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class ScriptConditionSearchTests extends AbstractWatcherIntegrationTestCase {
|
||||
|
||||
@Override
|
||||
protected List<Class<? extends Plugin>> pluginTypes() {
|
||||
List<Class<? extends Plugin>> types = super.pluginTypes();
|
||||
types.add(CustomScriptPlugin.class);
|
||||
return types;
|
||||
}
|
||||
|
||||
public static class CustomScriptPlugin extends MockScriptPlugin {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
|
||||
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
|
||||
|
||||
scripts.put("ctx.payload.aggregations.rate.buckets[0]?.doc_count >= 5", vars -> {
|
||||
List<?> buckets = (List<?>) XContentMapValues.extractValue("ctx.payload.aggregations.rate.buckets", vars);
|
||||
int docCount = (int) XContentMapValues.extractValue("doc_count", (Map<String, Object>) buckets.get(0));
|
||||
return docCount >= 5;
|
||||
});
|
||||
|
||||
scripts.put("ctx.payload.hits?.hits[0]?._score == 1.0", vars -> {
|
||||
List<Map<String, Object>> searchHits = (List<Map<String, Object>>) XContentMapValues.extractValue("ctx.payload.hits.hits",
|
||||
vars);
|
||||
double score = (double) XContentMapValues.extractValue("_score", searchHits.get(0));
|
||||
return score == 1.0;
|
||||
});
|
||||
|
||||
return scripts;
|
||||
}
|
||||
}
|
||||
|
||||
public void testExecuteWithAggs() throws Exception {
|
||||
client().prepareIndex("my-index", "my-type").setSource("@timestamp", "2005-01-01T00:00").get();
|
||||
client().prepareIndex("my-index", "my-type").setSource("@timestamp", "2005-01-01T00:10").get();
|
||||
client().prepareIndex("my-index", "my-type").setSource("@timestamp", "2005-01-01T00:20").get();
|
||||
client().prepareIndex("my-index", "my-type").setSource("@timestamp", "2005-01-01T00:30").get();
|
||||
refresh();
|
||||
|
||||
SearchResponse response = client().prepareSearch("my-index")
|
||||
.addAggregation(AggregationBuilders.dateHistogram("rate").field("@timestamp")
|
||||
.dateHistogramInterval(DateHistogramInterval.HOUR).order(BucketOrder.count(false)))
|
||||
.get();
|
||||
|
||||
ScriptService scriptService = internalCluster().getInstance(ScriptService.class);
|
||||
ScriptCondition condition = new ScriptCondition(
|
||||
mockScript("ctx.payload.aggregations.rate.buckets[0]?.doc_count >= 5"),
|
||||
scriptService);
|
||||
|
||||
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
|
||||
assertFalse(condition.execute(ctx).met());
|
||||
|
||||
client().prepareIndex("my-index", "my-type").setSource("@timestamp", "2005-01-01T00:40").get();
|
||||
refresh();
|
||||
|
||||
response = client().prepareSearch("my-index").addAggregation(AggregationBuilders.dateHistogram("rate").field("@timestamp")
|
||||
.dateHistogramInterval(DateHistogramInterval.HOUR).order(BucketOrder.count(false)))
|
||||
.get();
|
||||
|
||||
ctx = mockExecutionContext("_name", new Payload.XContent(response));
|
||||
assertThat(condition.execute(ctx).met(), is(true));
|
||||
}
|
||||
|
||||
public void testExecuteAccessHits() throws Exception {
|
||||
ScriptService scriptService = internalCluster().getInstance(ScriptService.class);
|
||||
ScriptCondition condition = new ScriptCondition(
|
||||
mockScript("ctx.payload.hits?.hits[0]?._score == 1.0"), scriptService);
|
||||
SearchHit hit = new SearchHit(0, "1", new Text("type"), null);
|
||||
hit.score(1f);
|
||||
hit.shard(new SearchShardTarget("a", new Index("a", "testUUID"), 0, null));
|
||||
|
||||
InternalSearchResponse internalSearchResponse = new InternalSearchResponse(new SearchHits(
|
||||
new SearchHit[]{hit}, 1L, 1f), null, null, null, false, false, 1);
|
||||
SearchResponse response = new SearchResponse(internalSearchResponse, "", 3, 3, 0, 500L, new ShardSearchFailure[0]);
|
||||
|
||||
WatchExecutionContext ctx = mockExecutionContext("_watch_name", new Payload.XContent(response));
|
||||
assertThat(condition.execute(ctx).met(), is(true));
|
||||
hit.score(2f);
|
||||
when(ctx.payload()).thenReturn(new Payload.XContent(response));
|
||||
assertThat(condition.execute(ctx).met(), is(false));
|
||||
}
|
||||
}
|
|
@ -72,6 +72,7 @@ import static java.util.Arrays.asList;
|
|||
import static java.util.Collections.singletonMap;
|
||||
import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds;
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
@ -202,7 +203,7 @@ public class ExecutionServiceTests extends ESTestCase {
|
|||
when(watch.input()).thenReturn(input);
|
||||
when(watch.condition()).thenReturn(condition);
|
||||
when(watch.transform()).thenReturn(watchTransform);
|
||||
when(watch.actions()).thenReturn(Arrays.asList(actionWrapper));
|
||||
when(watch.actions()).thenReturn(Collections.singletonList(actionWrapper));
|
||||
when(watch.status()).thenReturn(watchStatus);
|
||||
|
||||
WatchRecord watchRecord = executionService.execute(context);
|
||||
|
@ -221,6 +222,10 @@ public class ExecutionServiceTests extends ESTestCase {
|
|||
verify(watchTransform, times(1)).execute(context, payload);
|
||||
verify(action, times(1)).execute("_action", context, payload);
|
||||
|
||||
// test execution duration
|
||||
assertThat(watchRecord.result().executionDurationMs(), is(greaterThan(0L)));
|
||||
assertThat(watchRecord.result().executionTime(), is(notNullValue()));
|
||||
|
||||
// test stats
|
||||
XContentSource source = new XContentSource(jsonBuilder().map(executionService.usageStats()));
|
||||
assertThat(source.getValue("execution.actions._all.total_time_in_ms"), is(notNullValue()));
|
||||
|
|
|
@ -1,314 +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.xpack.watcher.execution;
|
||||
|
||||
import org.elasticsearch.action.ActionRequestValidationException;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.script.MockScriptPlugin;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
import org.elasticsearch.xpack.watcher.actions.ActionStatus;
|
||||
import org.elasticsearch.xpack.watcher.client.WatchSourceBuilder;
|
||||
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
|
||||
import org.elasticsearch.xpack.watcher.condition.NeverCondition;
|
||||
import org.elasticsearch.xpack.watcher.condition.ScriptCondition;
|
||||
import org.elasticsearch.xpack.watcher.history.HistoryStore;
|
||||
import org.elasticsearch.xpack.watcher.support.xcontent.ObjectPath;
|
||||
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchRequest;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchRequestBuilder;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchResponse;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.get.GetWatchRequest;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.get.GetWatchResponse;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchRequest;
|
||||
import org.elasticsearch.xpack.watcher.trigger.TriggerEvent;
|
||||
import org.elasticsearch.xpack.watcher.trigger.schedule.ScheduleTriggerEvent;
|
||||
import org.elasticsearch.xpack.watcher.watch.Watch;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
|
||||
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.loggingAction;
|
||||
import static org.elasticsearch.xpack.watcher.client.WatchSourceBuilders.watchBuilder;
|
||||
import static org.elasticsearch.xpack.watcher.input.InputBuilders.simpleInput;
|
||||
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
|
||||
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.cron;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
|
||||
public class ManualExecutionTests extends AbstractWatcherIntegrationTestCase {
|
||||
|
||||
@Override
|
||||
protected boolean enableSecurity() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Class<? extends Plugin>> pluginTypes() {
|
||||
List<Class<? extends Plugin>> types = super.pluginTypes();
|
||||
types.add(CustomScriptPlugin.class);
|
||||
return types;
|
||||
}
|
||||
|
||||
public static class CustomScriptPlugin extends MockScriptPlugin {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
|
||||
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
|
||||
|
||||
scripts.put("sleep", vars -> {
|
||||
Number millis = (Number) XContentMapValues.extractValue("millis", vars);
|
||||
if (millis != null) {
|
||||
try {
|
||||
Thread.sleep(millis.longValue());
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Unable to sleep, [millis] parameter is missing!");
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return scripts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pluginScriptLang() {
|
||||
return WATCHER_LANG;
|
||||
}
|
||||
}
|
||||
|
||||
public void testExecuteWatch() throws Exception {
|
||||
boolean ignoreCondition = randomBoolean();
|
||||
boolean recordExecution = randomBoolean();
|
||||
boolean conditionAlwaysTrue = randomBoolean();
|
||||
String action = randomFrom("_all", "log");
|
||||
|
||||
WatchSourceBuilder watchBuilder = watchBuilder()
|
||||
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
|
||||
.input(simpleInput("foo", "bar"))
|
||||
.condition(conditionAlwaysTrue ? AlwaysCondition.INSTANCE : NeverCondition.INSTANCE)
|
||||
.addAction("log", loggingAction("foobar"));
|
||||
|
||||
watcherClient().putWatch(new PutWatchRequest("_id", watchBuilder)).actionGet();
|
||||
|
||||
ExecuteWatchRequestBuilder executeWatchRequestBuilder = watcherClient().prepareExecuteWatch("_id");
|
||||
executeWatchRequestBuilder.setIgnoreCondition(ignoreCondition);
|
||||
executeWatchRequestBuilder.setRecordExecution(recordExecution);
|
||||
executeWatchRequestBuilder.setActionMode(action, ActionExecutionMode.SIMULATE);
|
||||
|
||||
refresh();
|
||||
long oldRecordCount = docCount(HistoryStore.INDEX_PREFIX_WITH_TEMPLATE + "*", HistoryStore.DOC_TYPE, matchAllQuery());
|
||||
|
||||
ExecuteWatchResponse executeWatchResponse = executeWatchRequestBuilder.get();
|
||||
Map<String, Object> responseMap = executeWatchResponse.getRecordSource().getAsMap();
|
||||
|
||||
refresh();
|
||||
long newRecordCount = docCount(HistoryStore.INDEX_PREFIX_WITH_TEMPLATE + "*", HistoryStore.DOC_TYPE, matchAllQuery());
|
||||
long expectedCount = oldRecordCount + (recordExecution ? 1 : 0);
|
||||
|
||||
assertThat("the expected count of history records should be [" + expectedCount + "]", newRecordCount, equalTo(expectedCount));
|
||||
|
||||
List<Map<String, Object>> actions = ObjectPath.eval("result.actions", responseMap);
|
||||
if (ignoreCondition) {
|
||||
assertThat("The action should have run", actions.size(), equalTo(1));
|
||||
} else if (!conditionAlwaysTrue) {
|
||||
assertThat("The action should not have run", actions.size(), equalTo(0));
|
||||
}
|
||||
|
||||
if (ignoreCondition || conditionAlwaysTrue) {
|
||||
assertThat("The action should have run simulated", actions.get(0).get("status"), is("simulated"));
|
||||
}
|
||||
|
||||
if (recordExecution) {
|
||||
GetWatchResponse response = watcherClient().getWatch(new GetWatchRequest("_id")).actionGet();
|
||||
if (ignoreCondition || conditionAlwaysTrue) {
|
||||
assertThat(response.getStatus().actionStatus("log").ackStatus().state(), is(ActionStatus.AckStatus.State.ACKABLE));
|
||||
} else {
|
||||
assertThat(response.getStatus().actionStatus("log").ackStatus().state(),
|
||||
is(ActionStatus.AckStatus.State.AWAITS_SUCCESSFUL_EXECUTION));
|
||||
}
|
||||
} else {
|
||||
String ackState = executeWatchResponse.getRecordSource().getValue("status.actions.log.ack.state");
|
||||
if (ignoreCondition || conditionAlwaysTrue) {
|
||||
assertThat(ackState, is(ActionStatus.AckStatus.State.ACKABLE.toString().toLowerCase(Locale.ROOT)));
|
||||
} else {
|
||||
assertThat(ackState, is(ActionStatus.AckStatus.State.AWAITS_SUCCESSFUL_EXECUTION.toString().toLowerCase(Locale.ROOT)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testExecutionWithInlineWatch() throws Exception {
|
||||
WatchSourceBuilder watchBuilder = watchBuilder()
|
||||
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
|
||||
.input(simpleInput("foo", "bar"))
|
||||
.condition(AlwaysCondition.INSTANCE)
|
||||
.addAction("log", loggingAction("foobar"));
|
||||
|
||||
ExecuteWatchRequestBuilder builder = watcherClient().prepareExecuteWatch()
|
||||
.setWatchSource(watchBuilder);
|
||||
if (randomBoolean()) {
|
||||
builder.setRecordExecution(false);
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
DateTime now = new DateTime(DateTimeZone.UTC);
|
||||
builder.setTriggerEvent(new ScheduleTriggerEvent(now, now));
|
||||
}
|
||||
|
||||
ExecuteWatchResponse executeWatchResponse = builder.get();
|
||||
assertThat(executeWatchResponse.getRecordId(), startsWith(ExecuteWatchRequest.INLINE_WATCH_ID));
|
||||
assertThat(executeWatchResponse.getRecordSource().getValue("watch_id").toString(), equalTo(ExecuteWatchRequest.INLINE_WATCH_ID));
|
||||
assertThat(executeWatchResponse.getRecordSource().getValue("state").toString(), equalTo("executed"));
|
||||
assertThat(executeWatchResponse.getRecordSource().getValue("trigger_event.type").toString(), equalTo("manual"));
|
||||
}
|
||||
|
||||
public void testExecutionWithInlineWatchWithRecordExecutionEnabled() throws Exception {
|
||||
WatchSourceBuilder watchBuilder = watchBuilder()
|
||||
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
|
||||
.input(simpleInput("foo", "bar"))
|
||||
.condition(AlwaysCondition.INSTANCE)
|
||||
.addAction("log", loggingAction("foobar"));
|
||||
|
||||
ActionRequestValidationException e = expectThrows(ActionRequestValidationException.class, () ->
|
||||
watcherClient().prepareExecuteWatch()
|
||||
.setWatchSource(watchBuilder)
|
||||
.setRecordExecution(true)
|
||||
.setTriggerEvent(new ScheduleTriggerEvent(new DateTime(DateTimeZone.UTC), new DateTime(DateTimeZone.UTC)))
|
||||
.get());
|
||||
assertThat(e.getMessage(), containsString("the execution of an inline watch cannot be recorded"));
|
||||
}
|
||||
|
||||
public void testExecutionWithInlineWatch_withWatchId() throws Exception {
|
||||
WatchSourceBuilder watchBuilder = watchBuilder()
|
||||
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
|
||||
.input(simpleInput("foo", "bar"))
|
||||
.condition(AlwaysCondition.INSTANCE)
|
||||
.addAction("log", loggingAction("foobar"));
|
||||
|
||||
try {
|
||||
watcherClient().prepareExecuteWatch()
|
||||
.setId("_id")
|
||||
.setWatchSource(watchBuilder)
|
||||
.setRecordExecution(false)
|
||||
.setTriggerEvent(new ScheduleTriggerEvent(new DateTime(DateTimeZone.UTC), new DateTime(DateTimeZone.UTC)))
|
||||
.get();
|
||||
fail();
|
||||
} catch (ActionRequestValidationException e) {
|
||||
assertThat(e.getMessage(),
|
||||
containsString("a watch execution request must either have a watch id or an inline watch source but not both"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testDifferentAlternativeInputs() throws Exception {
|
||||
WatchSourceBuilder watchBuilder = watchBuilder()
|
||||
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
|
||||
.addAction("log", loggingAction("foobar"));
|
||||
|
||||
watcherClient().putWatch(new PutWatchRequest("_id", watchBuilder)).actionGet();
|
||||
refresh(Watch.INDEX);
|
||||
|
||||
Map<String, Object> map1 = new HashMap<>();
|
||||
map1.put("foo", "bar");
|
||||
|
||||
Map<String, Object> map2 = new HashMap<>();
|
||||
map2.put("foo", map1);
|
||||
|
||||
ExecuteWatchResponse firstResponse = watcherClient().prepareExecuteWatch("_id")
|
||||
.setActionMode("_all", ActionExecutionMode.SIMULATE)
|
||||
.setAlternativeInput(map1)
|
||||
.setRecordExecution(true)
|
||||
.setTriggerEvent(new ScheduleTriggerEvent(new DateTime(DateTimeZone.UTC), new DateTime(DateTimeZone.UTC)))
|
||||
.get();
|
||||
|
||||
ExecuteWatchResponse secondResponse = watcherClient().prepareExecuteWatch("_id")
|
||||
.setActionMode("_all", ActionExecutionMode.SIMULATE)
|
||||
.setAlternativeInput(map2)
|
||||
.setRecordExecution(true)
|
||||
.setTriggerEvent(new ScheduleTriggerEvent(new DateTime(DateTimeZone.UTC), new DateTime(DateTimeZone.UTC)))
|
||||
.get();
|
||||
|
||||
String firstPayload = ObjectPath.eval("result.input.payload.foo", firstResponse.getRecordSource().getAsMap());
|
||||
assertThat(firstPayload, is("bar"));
|
||||
Map<String, String> secondPayload = ObjectPath.eval("result.input.payload", secondResponse.getRecordSource().getAsMap());
|
||||
assertThat(secondPayload, instanceOf(Map.class));
|
||||
}
|
||||
|
||||
public void testExecutionRequestDefaults() throws Exception {
|
||||
WatchSourceBuilder watchBuilder = watchBuilder()
|
||||
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
|
||||
.input(simpleInput("foo", "bar"))
|
||||
.condition(NeverCondition.INSTANCE)
|
||||
.defaultThrottlePeriod(TimeValue.timeValueHours(1))
|
||||
.addAction("log", loggingAction("foobar"));
|
||||
watcherClient().putWatch(new PutWatchRequest("_id", watchBuilder)).actionGet();
|
||||
|
||||
DateTime now = new DateTime(Clock.systemUTC().millis());
|
||||
TriggerEvent triggerEvent = new ScheduleTriggerEvent(now, now);
|
||||
|
||||
Map<String, Object> executeWatchResult = watcherClient().prepareExecuteWatch()
|
||||
.setId("_id")
|
||||
.setTriggerEvent(triggerEvent)
|
||||
.get().getRecordSource().getAsMap();
|
||||
|
||||
assertThat(ObjectPath.eval("state", executeWatchResult), equalTo(ExecutionState.EXECUTION_NOT_NEEDED.toString()));
|
||||
assertThat(ObjectPath.eval("result.input.payload.foo", executeWatchResult), equalTo("bar"));
|
||||
|
||||
watchBuilder = watchBuilder()
|
||||
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
|
||||
.input(simpleInput("foo", "bar"))
|
||||
.condition(AlwaysCondition.INSTANCE)
|
||||
.defaultThrottlePeriod(TimeValue.timeValueHours(1))
|
||||
.addAction("log", loggingAction("foobar"));
|
||||
watcherClient().putWatch(new PutWatchRequest("_id", watchBuilder)).actionGet();
|
||||
|
||||
executeWatchResult = watcherClient().prepareExecuteWatch()
|
||||
.setId("_id").setTriggerEvent(triggerEvent).setRecordExecution(true)
|
||||
.get().getRecordSource().getAsMap();
|
||||
|
||||
assertThat(ObjectPath.eval("state", executeWatchResult), equalTo(ExecutionState.EXECUTED.toString()));
|
||||
assertThat(ObjectPath.eval("result.input.payload.foo", executeWatchResult), equalTo("bar"));
|
||||
assertThat(ObjectPath.eval("result.actions.0.id", executeWatchResult), equalTo("log"));
|
||||
|
||||
executeWatchResult = watcherClient().prepareExecuteWatch()
|
||||
.setId("_id").setTriggerEvent(triggerEvent)
|
||||
.get().getRecordSource().getAsMap();
|
||||
|
||||
assertThat(ObjectPath.eval("state", executeWatchResult), equalTo(ExecutionState.THROTTLED.toString()));
|
||||
}
|
||||
|
||||
public void testWatchExecutionDuration() throws Exception {
|
||||
Script script = new Script(ScriptType.INLINE, WATCHER_LANG, "sleep", singletonMap("millis", 100L));
|
||||
WatchSourceBuilder watchBuilder = watchBuilder()
|
||||
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
|
||||
.input(simpleInput("foo", "bar"))
|
||||
.condition(new ScriptCondition(script))
|
||||
.addAction("log", loggingAction("foobar"));
|
||||
|
||||
watcherClient().preparePutWatch("_id").setSource(watchBuilder).get();
|
||||
refresh(Watch.INDEX);
|
||||
|
||||
ScheduleTriggerEvent triggerEvent = new ScheduleTriggerEvent(new DateTime(DateTimeZone.UTC), new DateTime(DateTimeZone.UTC));
|
||||
ExecuteWatchResponse executeWatchResponse = watcherClient().prepareExecuteWatch("_id").setTriggerEvent(triggerEvent).get();
|
||||
Integer duration = ObjectPath.eval("result.execution_duration", executeWatchResponse.getRecordSource().getAsMap());
|
||||
|
||||
assertThat(duration, greaterThanOrEqualTo(100));
|
||||
}
|
||||
}
|
|
@ -11,11 +11,9 @@ import org.elasticsearch.common.unit.TimeValue;
|
|||
import org.elasticsearch.test.http.MockResponse;
|
||||
import org.elasticsearch.test.http.MockWebServer;
|
||||
import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
|
||||
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
|
||||
import org.elasticsearch.xpack.watcher.history.HistoryStore;
|
||||
import org.elasticsearch.xpack.watcher.support.xcontent.ObjectPath;
|
||||
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.delete.DeleteWatchRequest;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.delete.DeleteWatchResponse;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchResponse;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.get.GetWatchResponse;
|
||||
|
@ -29,43 +27,14 @@ import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitC
|
|||
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.loggingAction;
|
||||
import static org.elasticsearch.xpack.watcher.client.WatchSourceBuilders.watchBuilder;
|
||||
import static org.elasticsearch.xpack.watcher.input.InputBuilders.httpInput;
|
||||
import static org.elasticsearch.xpack.watcher.input.InputBuilders.simpleInput;
|
||||
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
|
||||
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.interval;
|
||||
import static org.hamcrest.Matchers.hasKey;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
public class DeleteWatchTests extends AbstractWatcherIntegrationTestCase {
|
||||
|
||||
public void testDelete() throws Exception {
|
||||
ensureWatcherStarted();
|
||||
PutWatchResponse putResponse = watcherClient().preparePutWatch("_name").setSource(watchBuilder()
|
||||
.trigger(schedule(interval("5m")))
|
||||
.input(simpleInput())
|
||||
.condition(AlwaysCondition.INSTANCE)
|
||||
.addAction("_action1", loggingAction("anything")))
|
||||
.get();
|
||||
|
||||
assertThat(putResponse, notNullValue());
|
||||
assertThat(putResponse.isCreated(), is(true));
|
||||
|
||||
DeleteWatchResponse deleteResponse = watcherClient().deleteWatch(new DeleteWatchRequest("_name")).get();
|
||||
assertThat(deleteResponse, notNullValue());
|
||||
assertThat(deleteResponse.getId(), is("_name"));
|
||||
assertThat(deleteResponse.getVersion(), is(putResponse.getVersion() + 1));
|
||||
assertThat(deleteResponse.isFound(), is(true));
|
||||
}
|
||||
|
||||
public void testDeleteNotFound() throws Exception {
|
||||
DeleteWatchResponse response = watcherClient().deleteWatch(new DeleteWatchRequest("_name")).get();
|
||||
assertThat(response, notNullValue());
|
||||
assertThat(response.getId(), is("_name"));
|
||||
assertThat(response.getVersion(), is(1L));
|
||||
assertThat(response.isFound(), is(false));
|
||||
}
|
||||
|
||||
// This is a special case, since locking is removed
|
||||
// Deleting a watch while it is being executed is possible now
|
||||
// This test ensures that there are no leftovers, like a watch status without a watch in the watch store
|
||||
|
|
|
@ -9,27 +9,17 @@ import org.elasticsearch.common.unit.TimeValue;
|
|||
import org.elasticsearch.xpack.watcher.actions.ActionStatus;
|
||||
import org.elasticsearch.xpack.watcher.client.WatcherClient;
|
||||
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
|
||||
import org.elasticsearch.xpack.watcher.condition.NeverCondition;
|
||||
import org.elasticsearch.xpack.watcher.execution.ActionExecutionMode;
|
||||
import org.elasticsearch.xpack.watcher.execution.Wid;
|
||||
import org.elasticsearch.xpack.watcher.support.WatcherDateTimeUtils;
|
||||
import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource;
|
||||
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.ack.AckWatchRequestBuilder;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.ack.AckWatchResponse;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchRequestBuilder;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchResponse;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.get.GetWatchResponse;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
|
||||
import org.elasticsearch.xpack.watcher.trigger.schedule.ScheduleTriggerEvent;
|
||||
import org.elasticsearch.xpack.watcher.watch.WatchStatus;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.loggingAction;
|
||||
import static org.elasticsearch.xpack.watcher.client.WatchSourceBuilders.watchBuilder;
|
||||
import static org.elasticsearch.xpack.watcher.input.InputBuilders.simpleInput;
|
||||
|
@ -84,149 +74,6 @@ public class ExecuteWatchTests extends AbstractWatcherIntegrationTestCase {
|
|||
assertValue(record, "status.actions.log.ack.state", is("ackable"));
|
||||
}
|
||||
|
||||
public void testExecuteCustomTriggerData() throws Exception {
|
||||
WatcherClient watcherClient = watcherClient();
|
||||
|
||||
PutWatchResponse putWatchResponse = watcherClient.preparePutWatch()
|
||||
.setId("_id")
|
||||
.setSource(watchBuilder()
|
||||
.trigger(schedule(cron("0/5 * * * * ? 2099")))
|
||||
.input(simpleInput("foo", "bar"))
|
||||
.condition(AlwaysCondition.INSTANCE)
|
||||
.addAction("log", loggingAction("_text")))
|
||||
.get();
|
||||
|
||||
assertThat(putWatchResponse.isCreated(), is(true));
|
||||
|
||||
DateTime triggeredTime = DateTime.now(DateTimeZone.UTC);
|
||||
DateTime scheduledTime = randomBoolean() ? triggeredTime.minusDays(1) : triggeredTime;
|
||||
|
||||
ExecuteWatchRequestBuilder requestBuilder = watcherClient.prepareExecuteWatch("_id");
|
||||
if (randomBoolean()) {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("triggered_time", WatcherDateTimeUtils.formatDate(triggeredTime));
|
||||
if (scheduledTime != triggeredTime) {
|
||||
data.put("scheduled_time", WatcherDateTimeUtils.formatDate(scheduledTime));
|
||||
}
|
||||
requestBuilder.setTriggerData(data);
|
||||
} else {
|
||||
ScheduleTriggerEvent event = new ScheduleTriggerEvent(triggeredTime, scheduledTime);
|
||||
requestBuilder.setTriggerEvent(event);
|
||||
}
|
||||
ExecuteWatchResponse response = requestBuilder.get();
|
||||
|
||||
assertThat(response, notNullValue());
|
||||
assertThat(response.getRecordId(), notNullValue());
|
||||
Wid wid = new Wid(response.getRecordId());
|
||||
assertThat(wid.watchId(), is("_id"));
|
||||
|
||||
XContentSource record = response.getRecordSource();
|
||||
assertValue(record, "watch_id", is("_id"));
|
||||
assertValue(record, "trigger_event.type", is("manual"));
|
||||
assertValue(record, "trigger_event.triggered_time", is(WatcherDateTimeUtils.formatDate(triggeredTime)));
|
||||
assertValue(record, "trigger_event.manual.schedule.scheduled_time", is(WatcherDateTimeUtils.formatDate(scheduledTime)));
|
||||
assertValue(record, "state", is("executed"));
|
||||
assertValue(record, "input.simple.foo", is("bar"));
|
||||
assertValue(record, "condition.always", notNullValue());
|
||||
assertValue(record, "result.execution_time", notNullValue());
|
||||
assertValue(record, "result.execution_duration", notNullValue());
|
||||
assertValue(record, "result.input.type", is("simple"));
|
||||
assertValue(record, "result.input.payload.foo", is("bar"));
|
||||
assertValue(record, "result.condition.type", is("always"));
|
||||
assertValue(record, "result.condition.met", is(true));
|
||||
assertValue(record, "result.actions.0.id", is("log"));
|
||||
assertValue(record, "result.actions.0.type", is("logging"));
|
||||
assertValue(record, "result.actions.0.status", is("success"));
|
||||
assertValue(record, "result.actions.0.logging.logged_text", is("_text"));
|
||||
}
|
||||
|
||||
public void testExecuteAlternativeInput() throws Exception {
|
||||
WatcherClient watcherClient = watcherClient();
|
||||
|
||||
PutWatchResponse putWatchResponse = watcherClient.preparePutWatch()
|
||||
.setId("_id")
|
||||
.setSource(watchBuilder()
|
||||
.trigger(schedule(cron("0/5 * * * * ? 2099")))
|
||||
.input(simpleInput("foo", "bar"))
|
||||
.condition(AlwaysCondition.INSTANCE)
|
||||
.addAction("log", loggingAction("_text")))
|
||||
.get();
|
||||
|
||||
assertThat(putWatchResponse.isCreated(), is(true));
|
||||
|
||||
ExecuteWatchResponse response = watcherClient.prepareExecuteWatch("_id")
|
||||
.setAlternativeInput(singletonMap("foo1", "bar1"))
|
||||
.get();
|
||||
assertThat(response, notNullValue());
|
||||
assertThat(response.getRecordId(), notNullValue());
|
||||
Wid wid = new Wid(response.getRecordId());
|
||||
assertThat(wid.watchId(), is("_id"));
|
||||
|
||||
XContentSource record = response.getRecordSource();
|
||||
assertValue(record, "watch_id", is("_id"));
|
||||
assertValue(record, "trigger_event.type", is("manual"));
|
||||
assertValue(record, "trigger_event.triggered_time", notNullValue());
|
||||
String triggeredTime = record.getValue("trigger_event.triggered_time");
|
||||
assertValue(record, "trigger_event.manual.schedule.scheduled_time", is(triggeredTime));
|
||||
assertValue(record, "state", is("executed"));
|
||||
assertValue(record, "input.simple.foo", is("bar")); // this is the original input
|
||||
assertValue(record, "condition.always", notNullValue());
|
||||
assertValue(record, "result.execution_time", notNullValue());
|
||||
assertValue(record, "result.execution_duration", notNullValue());
|
||||
assertValue(record, "result.input.type", is("simple"));
|
||||
assertValue(record, "result.input.payload.foo1", is("bar1")); // this is the alternative one
|
||||
assertValue(record, "result.condition.type", is("always"));
|
||||
assertValue(record, "result.condition.met", is(true));
|
||||
assertValue(record, "result.actions.0.id", is("log"));
|
||||
assertValue(record, "result.actions.0.type", is("logging"));
|
||||
assertValue(record, "result.actions.0.status", is("success"));
|
||||
assertValue(record, "result.actions.0.logging.logged_text", is("_text"));
|
||||
}
|
||||
|
||||
public void testExecuteIgnoreCondition() throws Exception {
|
||||
WatcherClient watcherClient = watcherClient();
|
||||
|
||||
PutWatchResponse putWatchResponse = watcherClient.preparePutWatch()
|
||||
.setId("_id")
|
||||
.setSource(watchBuilder()
|
||||
.trigger(schedule(cron("0/5 * * * * ? 2099")))
|
||||
.input(simpleInput("foo", "bar"))
|
||||
.condition(NeverCondition.INSTANCE)
|
||||
.addAction("log", loggingAction("_text")))
|
||||
.get();
|
||||
|
||||
assertThat(putWatchResponse.isCreated(), is(true));
|
||||
|
||||
ExecuteWatchResponse response = watcherClient.prepareExecuteWatch("_id")
|
||||
.setIgnoreCondition(true)
|
||||
.get();
|
||||
|
||||
assertThat(response, notNullValue());
|
||||
assertThat(response.getRecordId(), notNullValue());
|
||||
Wid wid = new Wid(response.getRecordId());
|
||||
assertThat(wid.watchId(), is("_id"));
|
||||
|
||||
XContentSource record = response.getRecordSource();
|
||||
assertValue(record, "watch_id", is("_id"));
|
||||
assertValue(record, "trigger_event.type", is("manual"));
|
||||
assertValue(record, "trigger_event.triggered_time", notNullValue());
|
||||
String triggeredTime = record.getValue("trigger_event.triggered_time");
|
||||
assertValue(record, "trigger_event.manual.schedule.scheduled_time", is(triggeredTime));
|
||||
assertValue(record, "state", is("executed"));
|
||||
assertValue(record, "input.simple.foo", is("bar"));
|
||||
assertValue(record, "condition.never", notNullValue()); // the original condition
|
||||
assertValue(record, "result.execution_time", notNullValue());
|
||||
assertValue(record, "result.execution_duration", notNullValue());
|
||||
assertValue(record, "result.input.type", is("simple"));
|
||||
assertValue(record, "result.input.payload.foo", is("bar"));
|
||||
assertValue(record, "result.condition.type", is("always")); // when ignored, the condition is replaced with "always"
|
||||
assertValue(record, "result.condition.met", is(true));
|
||||
assertValue(record, "result.actions.0.id", is("log"));
|
||||
assertValue(record, "result.actions.0.type", is("logging"));
|
||||
assertValue(record, "result.actions.0.status", is("success"));
|
||||
assertValue(record, "result.actions.0.logging.logged_text", is("_text"));
|
||||
}
|
||||
|
||||
public void testExecuteActionMode() throws Exception {
|
||||
final WatcherClient watcherClient = watcherClient();
|
||||
|
||||
|
|
|
@ -1,54 +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.xpack.watcher.transport.action.put;
|
||||
|
||||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.xpack.watcher.client.WatchSourceBuilder;
|
||||
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
|
||||
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
|
||||
|
||||
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.loggingAction;
|
||||
import static org.elasticsearch.xpack.watcher.client.WatchSourceBuilders.watchBuilder;
|
||||
import static org.elasticsearch.xpack.watcher.input.InputBuilders.simpleInput;
|
||||
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
|
||||
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.interval;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
public class PutWatchTests extends AbstractWatcherIntegrationTestCase {
|
||||
public void testPut() throws Exception {
|
||||
WatchSourceBuilder source = watchBuilder()
|
||||
.trigger(schedule(interval("5m")));
|
||||
|
||||
if (randomBoolean()) {
|
||||
source.input(simpleInput());
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
source.condition(AlwaysCondition.INSTANCE);
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
source.addAction("_action1", loggingAction("{{ctx.watch_id}}"));
|
||||
}
|
||||
|
||||
PutWatchResponse response = watcherClient().preparePutWatch("_name").setSource(source).get();
|
||||
|
||||
assertThat(response, notNullValue());
|
||||
assertThat(response.isCreated(), is(true));
|
||||
assertThat(response.getVersion(), is(1L));
|
||||
}
|
||||
|
||||
public void testPutNoTrigger() throws Exception {
|
||||
ElasticsearchException exception = expectThrows(ElasticsearchException.class,
|
||||
() -> watcherClient().preparePutWatch("_name").setSource(watchBuilder()
|
||||
.input(simpleInput())
|
||||
.condition(AlwaysCondition.INSTANCE)
|
||||
.addAction("_action1", loggingAction("{{ctx.watch_id}}")))
|
||||
.get());
|
||||
assertEquals("Failed to build ToXContent", exception.getMessage());
|
||||
}
|
||||
}
|
|
@ -50,6 +50,9 @@ import org.elasticsearch.xpack.watcher.actions.email.ExecutableEmailAction;
|
|||
import org.elasticsearch.xpack.watcher.actions.index.ExecutableIndexAction;
|
||||
import org.elasticsearch.xpack.watcher.actions.index.IndexAction;
|
||||
import org.elasticsearch.xpack.watcher.actions.index.IndexActionFactory;
|
||||
import org.elasticsearch.xpack.watcher.actions.logging.ExecutableLoggingAction;
|
||||
import org.elasticsearch.xpack.watcher.actions.logging.LoggingAction;
|
||||
import org.elasticsearch.xpack.watcher.actions.logging.LoggingActionFactory;
|
||||
import org.elasticsearch.xpack.watcher.actions.throttler.ActionThrottler;
|
||||
import org.elasticsearch.xpack.watcher.actions.webhook.ExecutableWebhookAction;
|
||||
import org.elasticsearch.xpack.watcher.actions.webhook.WebhookAction;
|
||||
|
@ -68,6 +71,7 @@ import org.elasticsearch.xpack.watcher.input.InputBuilders;
|
|||
import org.elasticsearch.xpack.watcher.input.InputFactory;
|
||||
import org.elasticsearch.xpack.watcher.input.InputRegistry;
|
||||
import org.elasticsearch.xpack.watcher.input.none.ExecutableNoneInput;
|
||||
import org.elasticsearch.xpack.watcher.input.none.NoneInput;
|
||||
import org.elasticsearch.xpack.watcher.input.search.ExecutableSearchInput;
|
||||
import org.elasticsearch.xpack.watcher.input.search.SearchInput;
|
||||
import org.elasticsearch.xpack.watcher.input.search.SearchInputFactory;
|
||||
|
@ -76,6 +80,7 @@ import org.elasticsearch.xpack.watcher.input.simple.SimpleInput;
|
|||
import org.elasticsearch.xpack.watcher.input.simple.SimpleInputFactory;
|
||||
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateRequest;
|
||||
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateService;
|
||||
import org.elasticsearch.xpack.watcher.test.MockTextTemplateEngine;
|
||||
import org.elasticsearch.xpack.watcher.test.WatcherTestUtils;
|
||||
import org.elasticsearch.xpack.watcher.transform.ExecutableTransform;
|
||||
import org.elasticsearch.xpack.watcher.transform.TransformFactory;
|
||||
|
@ -132,7 +137,9 @@ import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource;
|
|||
import static org.elasticsearch.xpack.watcher.input.InputBuilders.searchInput;
|
||||
import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.templateRequest;
|
||||
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
@ -375,6 +382,76 @@ public class WatchTests extends ESTestCase {
|
|||
assertThat(((ScriptQueryBuilder) searchRequest.source().query()).script().getLang(), equalTo(Script.DEFAULT_SCRIPT_LANG));
|
||||
}
|
||||
|
||||
public void testParseWatchWithoutInput() throws Exception {
|
||||
try (XContentBuilder builder = jsonBuilder()) {
|
||||
builder.startObject();
|
||||
|
||||
builder.startObject("trigger").startObject("schedule").field("interval", "99w").endObject().endObject();
|
||||
builder.startObject("condition").startObject("always").endObject().endObject();
|
||||
builder.startObject("actions").startObject("logme")
|
||||
.startObject("logging").field("text", "foo").endObject()
|
||||
.endObject().endObject();
|
||||
builder.endObject();
|
||||
|
||||
Watch.Parser parser = createWatchparser();
|
||||
Watch watch = parser.parse("_id", false, builder.bytes(), XContentType.JSON);
|
||||
assertThat(watch, is(notNullValue()));
|
||||
assertThat(watch.input().type(), is(NoneInput.TYPE));
|
||||
}
|
||||
}
|
||||
|
||||
public void testParseWatchWithoutAction() throws Exception {
|
||||
try (XContentBuilder builder = jsonBuilder()) {
|
||||
builder.startObject();
|
||||
|
||||
builder.startObject("trigger").startObject("schedule").field("interval", "99w").endObject().endObject();
|
||||
builder.startObject("input").startObject("simple").endObject().endObject();
|
||||
builder.startObject("condition").startObject("always").endObject().endObject();
|
||||
builder.endObject();
|
||||
|
||||
Watch.Parser parser = createWatchparser();
|
||||
Watch watch = parser.parse("_id", false, builder.bytes(), XContentType.JSON);
|
||||
assertThat(watch, is(notNullValue()));
|
||||
assertThat(watch.actions(), hasSize(0));
|
||||
}
|
||||
}
|
||||
|
||||
public void testParseWatchWithoutTriggerDoesNotWork() throws Exception {
|
||||
try (XContentBuilder builder = jsonBuilder()) {
|
||||
builder.startObject();
|
||||
|
||||
builder.startObject("input").startObject("simple").endObject().endObject();
|
||||
builder.startObject("condition").startObject("always").endObject().endObject();
|
||||
builder.startObject("actions").startObject("logme")
|
||||
.startObject("logging").field("text", "foo").endObject()
|
||||
.endObject().endObject();
|
||||
builder.endObject();
|
||||
|
||||
Watch.Parser parser = createWatchparser();
|
||||
ElasticsearchParseException e = expectThrows(ElasticsearchParseException.class,
|
||||
() -> parser.parse("_id", false, builder.bytes(), XContentType.JSON));
|
||||
assertThat(e.getMessage(), is("could not parse watch [_id]. missing required field [trigger]"));
|
||||
}
|
||||
}
|
||||
|
||||
private Watch.Parser createWatchparser() throws Exception {
|
||||
LoggingAction loggingAction = new LoggingAction(new TextTemplate("foo"), null, null);
|
||||
List<ActionWrapper> actions = Collections.singletonList(new ActionWrapper("_logging_", randomThrottler(), null, null,
|
||||
new ExecutableLoggingAction(loggingAction, logger, settings, new MockTextTemplateEngine())));
|
||||
|
||||
ScheduleRegistry scheduleRegistry = registry(new IntervalSchedule(new IntervalSchedule.Interval(1,
|
||||
IntervalSchedule.Interval.Unit.SECONDS)));
|
||||
TriggerEngine triggerEngine = new ParseOnlyScheduleTriggerEngine(Settings.EMPTY, scheduleRegistry, Clock.systemUTC());
|
||||
TriggerService triggerService = new TriggerService(Settings.EMPTY, singleton(triggerEngine));
|
||||
|
||||
ConditionRegistry conditionRegistry = conditionRegistry();
|
||||
InputRegistry inputRegistry = registry(SimpleInput.TYPE);
|
||||
TransformRegistry transformRegistry = transformRegistry();
|
||||
ActionRegistry actionRegistry = registry(actions, conditionRegistry, transformRegistry);
|
||||
|
||||
return new Watch.Parser(settings, triggerService, actionRegistry, inputRegistry, null, Clock.systemUTC());
|
||||
}
|
||||
|
||||
private static Schedule randomSchedule() {
|
||||
String type = randomFrom(CronSchedule.TYPE, HourlySchedule.TYPE, DailySchedule.TYPE, WeeklySchedule.TYPE, MonthlySchedule.TYPE,
|
||||
YearlySchedule.TYPE, IntervalSchedule.TYPE);
|
||||
|
@ -541,6 +618,9 @@ public class WatchTests extends ESTestCase {
|
|||
parsers.put(WebhookAction.TYPE, new WebhookActionFactory(settings, httpClient,
|
||||
new HttpRequestTemplate.Parser(authRegistry), templateEngine));
|
||||
break;
|
||||
case LoggingAction.TYPE:
|
||||
parsers.put(LoggingAction.TYPE, new LoggingActionFactory(settings, new MockTextTemplateEngine()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new ActionRegistry(unmodifiableMap(parsers), conditionRegistry, transformRegistry, Clock.systemUTC(), licenseState);
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
---
|
||||
"Test delete watch api":
|
||||
setup:
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
---
|
||||
teardown:
|
||||
- do:
|
||||
xpack.watcher.delete_watch:
|
||||
id: "my_watch"
|
||||
ignore: 404
|
||||
|
||||
---
|
||||
"Test delete watch api":
|
||||
- do:
|
||||
xpack.watcher.put_watch:
|
||||
id: "my_watch"
|
||||
|
@ -37,6 +46,7 @@
|
|||
}
|
||||
}
|
||||
- match: { _id: "my_watch" }
|
||||
- match: { created: true }
|
||||
|
||||
- do:
|
||||
xpack.watcher.delete_watch:
|
||||
|
@ -51,10 +61,6 @@
|
|||
|
||||
---
|
||||
"Non existent watch returns 404":
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
- do:
|
||||
xpack.watcher.delete_watch:
|
||||
id: "non-existent-watch"
|
||||
|
|
|
@ -106,3 +106,49 @@ teardown:
|
|||
xpack.watcher.execute_watch:
|
||||
id: "non-existent-watch"
|
||||
catch: missing
|
||||
|
||||
---
|
||||
"Test execute watch with alternative input":
|
||||
|
||||
- do:
|
||||
xpack.watcher.put_watch:
|
||||
id: "test_watch"
|
||||
body: >
|
||||
{
|
||||
"trigger": {
|
||||
"schedule" : { "cron" : "0 0 0 1 * ? 2099" }
|
||||
},
|
||||
"input": {
|
||||
"simple": {
|
||||
"foo": "bar"
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
"indexme" : {
|
||||
"index" : {
|
||||
"index" : "my-index",
|
||||
"doc_type" : "my-type",
|
||||
"doc_id": "my-id"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
- match: { _id: "test_watch" }
|
||||
- match: { created: true }
|
||||
|
||||
- do:
|
||||
xpack.watcher.execute_watch:
|
||||
id: "test_watch"
|
||||
body: >
|
||||
{
|
||||
"alternative_input" : {
|
||||
"spam" : "eggs"
|
||||
}
|
||||
}
|
||||
|
||||
- match: { watch_record.watch_id: "test_watch" }
|
||||
- match: { watch_record.state: "executed" }
|
||||
- match: { watch_record.status.state.active: true }
|
||||
- is_true: watch_record.node
|
||||
- is_false: watch_record.result.input.payload.foo
|
||||
- is_true: watch_record.result.input.payload.spam
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
---
|
||||
setup:
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
---
|
||||
teardown:
|
||||
- do:
|
||||
xpack.watcher.delete_watch:
|
||||
id: "test_watch"
|
||||
ignore: 404
|
||||
|
||||
---
|
||||
"Test execute watch api works with throttling":
|
||||
- do:
|
||||
xpack.watcher.put_watch:
|
||||
id: "test_watch"
|
||||
body: >
|
||||
{
|
||||
"trigger": {
|
||||
"schedule" : { "cron" : "0 0 0 1 * ? 2099" }
|
||||
},
|
||||
"input": {
|
||||
"simple": {
|
||||
"foo": "bar"
|
||||
}
|
||||
},
|
||||
"condition": {
|
||||
"never": {}
|
||||
},
|
||||
"actions": {
|
||||
"logging" : {
|
||||
"logging" : {
|
||||
"text" : "logging text from test: execute_watch/30_throttled.yml"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
- match: { _id: "test_watch" }
|
||||
- match: { created: true }
|
||||
|
||||
- do:
|
||||
xpack.watcher.execute_watch:
|
||||
id: "test_watch"
|
||||
body: >
|
||||
{
|
||||
"trigger_data" : {
|
||||
"triggered_time" : "2012-12-12T12:12:12.120Z",
|
||||
"scheduled_time" : "2000-12-12T12:12:12.120Z"
|
||||
}
|
||||
}
|
||||
|
||||
- match: { watch_record.watch_id: "test_watch" }
|
||||
- match: { watch_record.trigger_event.type: "manual" }
|
||||
- match: { watch_record.trigger_event.triggered_time: "2012-12-12T12:12:12.120Z" }
|
||||
- match: { watch_record.trigger_event.manual.schedule.scheduled_time: "2000-12-12T12:12:12.120Z" }
|
||||
- match: { watch_record.state: "execution_not_needed" }
|
||||
- match: { watch_record.status.state.active: true }
|
||||
|
||||
- do:
|
||||
xpack.watcher.put_watch:
|
||||
id: "test_watch"
|
||||
body: >
|
||||
{
|
||||
"trigger": {
|
||||
"schedule" : { "cron" : "0 0 0 1 * ? 2099" }
|
||||
},
|
||||
"input": {
|
||||
"simple": {
|
||||
"foo": "bar"
|
||||
}
|
||||
},
|
||||
"condition": {
|
||||
"always": {}
|
||||
},
|
||||
"throttle_period" : "1h",
|
||||
"actions": {
|
||||
"logging" : {
|
||||
"logging" : {
|
||||
"text" : "logging text from test: execute_watch/30_throttled.yml"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
- match: { _id: "test_watch" }
|
||||
|
||||
- do:
|
||||
xpack.watcher.execute_watch:
|
||||
id: "test_watch"
|
||||
body: >
|
||||
{
|
||||
"trigger_data" : {
|
||||
"triggered_time" : "2012-12-12T12:12:12.120Z",
|
||||
"scheduled_time" : "2000-12-12T12:12:12.120Z"
|
||||
},
|
||||
"record_execution": true
|
||||
}
|
||||
|
||||
- match: { watch_record.watch_id: "test_watch" }
|
||||
- match: { watch_record.state: "executed" }
|
||||
|
||||
- do:
|
||||
xpack.watcher.execute_watch:
|
||||
id: "test_watch"
|
||||
body: >
|
||||
{
|
||||
"trigger_data" : {
|
||||
"triggered_time" : "2012-12-12T12:12:12.120Z",
|
||||
"scheduled_time" : "2000-12-12T12:12:12.120Z"
|
||||
},
|
||||
"record_execution": true
|
||||
}
|
||||
|
||||
- match: { watch_record.watch_id: "test_watch" }
|
||||
- match: { watch_record.state: "throttled" }
|
||||
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
setup:
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
---
|
||||
teardown:
|
||||
- do:
|
||||
xpack.watcher.delete_watch:
|
||||
id: "test_watch"
|
||||
ignore: 404
|
||||
|
||||
---
|
||||
"Test execute watch api can ignore conditions":
|
||||
- do:
|
||||
xpack.watcher.put_watch:
|
||||
id: "test_watch"
|
||||
body: >
|
||||
{
|
||||
"trigger": {
|
||||
"schedule" : { "cron" : "0 0 0 1 * ? 2099" }
|
||||
},
|
||||
"input": {
|
||||
"simple": {
|
||||
"foo": "bar"
|
||||
}
|
||||
},
|
||||
"condition": {
|
||||
"never": {}
|
||||
},
|
||||
"actions": {
|
||||
"logging" : {
|
||||
"logging" : {
|
||||
"text" : "logging text from test: execute_watch/30_throttled.yml"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
- match: { _id: "test_watch" }
|
||||
- match: { created: true }
|
||||
|
||||
- do:
|
||||
xpack.watcher.execute_watch:
|
||||
id: "test_watch"
|
||||
body: >
|
||||
{
|
||||
"ignore_condition" : true
|
||||
}
|
||||
|
||||
- match: { watch_record.watch_id: "test_watch" }
|
||||
- match: { watch_record.input.simple.foo: "bar" }
|
||||
- match: { watch_record.trigger_event.type: "manual" }
|
||||
- match: { watch_record.state: "executed" }
|
||||
- match: { watch_record.status.state.active: true }
|
||||
- match: { watch_record.status.actions.logging.ack.state: "ackable" }
|
||||
- is_true: watch_record.condition.never
|
||||
- is_true: watch_record.result.execution_time
|
||||
- is_true: watch_record.result.execution_duration
|
||||
- match: { watch_record.result.input.type: "simple" }
|
||||
- match: { watch_record.result.input.payload.foo: "bar" }
|
||||
- match: { watch_record.result.condition.type: "always" }
|
||||
- match: { watch_record.result.condition.met: true }
|
|
@ -0,0 +1,71 @@
|
|||
---
|
||||
setup:
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
---
|
||||
teardown:
|
||||
- do:
|
||||
xpack.watcher.delete_watch:
|
||||
id: "test_watch"
|
||||
ignore: 404
|
||||
|
||||
---
|
||||
"Test execute watch api supports action modes":
|
||||
- do:
|
||||
xpack.watcher.put_watch:
|
||||
id: "test_watch"
|
||||
body: >
|
||||
{
|
||||
"trigger": {
|
||||
"schedule" : { "cron" : "0 0 0 1 * ? 2099" }
|
||||
},
|
||||
"input": {
|
||||
"simple": {
|
||||
"foo": "bar"
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
"logging" : {
|
||||
"logging" : {
|
||||
"text" : "logging text from test: execute_watch/30_throttled.yml"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
- match: { _id: "test_watch" }
|
||||
- match: { created: true }
|
||||
|
||||
- do:
|
||||
xpack.watcher.execute_watch:
|
||||
id: "test_watch"
|
||||
body: >
|
||||
{
|
||||
"action_modes" : {
|
||||
"logging" : "simulate"
|
||||
}
|
||||
}
|
||||
|
||||
- match: { watch_record.watch_id: "test_watch" }
|
||||
- match: { watch_record.trigger_event.type: "manual" }
|
||||
- match: { watch_record.state: "executed" }
|
||||
- match: { watch_record.result.actions.0.id: "logging" }
|
||||
- match: { watch_record.result.actions.0.status: "simulated" }
|
||||
|
||||
- do:
|
||||
xpack.watcher.execute_watch:
|
||||
id: "test_watch"
|
||||
body: >
|
||||
{
|
||||
"action_modes" : {
|
||||
"_all" : "simulate"
|
||||
}
|
||||
}
|
||||
|
||||
- match: { watch_record.watch_id: "test_watch" }
|
||||
- match: { watch_record.trigger_event.type: "manual" }
|
||||
- match: { watch_record.state: "executed" }
|
||||
- match: { watch_record.result.actions.0.id: "logging" }
|
||||
- match: { watch_record.result.actions.0.status: "simulated" }
|
||||
|
Loading…
Reference in New Issue