Watcher: Ignore deactivated state with execute watch API (elastic/x-pack-elasticsearch#4054)
If a watch is not active, it should still be executed, if it is called via the execute watch API. This commit adds an additional method to the execution context to check for this, which returns true for a manual execution context but checks the watch status for the triggered one. Original commit: elastic/x-pack-elasticsearch@18f3f9e84b
This commit is contained in:
parent
a68051405a
commit
955b0dddad
|
@ -68,6 +68,11 @@ public abstract class WatchExecutionContext {
|
|||
|
||||
public abstract boolean skipThrottling(String actionId);
|
||||
|
||||
/**
|
||||
* @return true if execution is allowed (this depends on the type of the watch context)
|
||||
*/
|
||||
public abstract boolean shouldBeExecuted();
|
||||
|
||||
/**
|
||||
* @return true if this execution should be recorded in the .watcher-history index
|
||||
*/
|
||||
|
|
|
@ -300,7 +300,7 @@ public class ExecutionService extends AbstractComponent {
|
|||
}
|
||||
|
||||
if (ctx.watch() != null) {
|
||||
if (ctx.watch().status().state().isActive()) {
|
||||
if (ctx.shouldBeExecuted()) {
|
||||
logger.debug("executing watch [{}]", watchId);
|
||||
|
||||
record = executeInner(ctx);
|
||||
|
@ -308,7 +308,7 @@ public class ExecutionService extends AbstractComponent {
|
|||
updateWatchStatus(ctx.watch());
|
||||
}
|
||||
} else {
|
||||
logger.debug("not executing watch [{}] because it is marked as inactive", watchId);
|
||||
logger.debug("not executing watch [{}]", watchId);
|
||||
record = ctx.abortBeforeExecution(ExecutionState.EXECUTION_NOT_NEEDED, "Watch is not active");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,6 +95,13 @@ public class ManualExecutionContext extends WatchExecutionContext {
|
|||
return mode != null && mode.force();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldBeExecuted() {
|
||||
// we always want to execute a manually triggered watch as the user has triggered this via an
|
||||
// external API call
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean recordExecution() {
|
||||
return recordExecution;
|
||||
|
|
|
@ -44,6 +44,11 @@ public class TriggeredExecutionContext extends WatchExecutionContext {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldBeExecuted() {
|
||||
return watch().status().state().isActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean recordExecution() {
|
||||
return true;
|
||||
|
|
|
@ -1037,6 +1037,42 @@ public class ExecutionServiceTests extends ESTestCase {
|
|||
assertThat(assertionsTriggered.get(), is(true));
|
||||
}
|
||||
|
||||
public void testManualWatchExecutionContextGetsAlwaysExecuted() throws Exception {
|
||||
Watch watch = mock(Watch.class);
|
||||
when(watch.id()).thenReturn("_id");
|
||||
|
||||
DateTime now = new DateTime(clock.millis());
|
||||
ScheduleTriggerEvent event = new ScheduleTriggerEvent("_id", now, now);
|
||||
ManualExecutionContext ctx = ManualExecutionContext.builder(watch, true,
|
||||
new ManualTriggerEvent("foo", event), timeValueSeconds(5)).build();
|
||||
|
||||
when(watch.input()).thenReturn(input);
|
||||
Condition.Result conditionResult = InternalAlwaysCondition.RESULT_INSTANCE;
|
||||
ExecutableCondition condition = mock(ExecutableCondition.class);
|
||||
when(condition.execute(any(WatchExecutionContext.class))).thenReturn(conditionResult);
|
||||
when(watch.condition()).thenReturn(condition);
|
||||
|
||||
Action.Result actionResult = mock(Action.Result.class);
|
||||
when(actionResult.type()).thenReturn("_action_type");
|
||||
when(actionResult.status()).thenReturn(Action.Result.Status.SUCCESS);
|
||||
ExecutableAction action = mock(ExecutableAction.class);
|
||||
when(action.logger()).thenReturn(logger);
|
||||
when(action.execute(eq("_action"), eq(ctx), eq(payload))).thenReturn(actionResult);
|
||||
|
||||
ActionWrapper actionWrapper = mock(ActionWrapper.class);
|
||||
ActionWrapperResult actionWrapperResult = new ActionWrapperResult("_action", actionResult);
|
||||
when(actionWrapper.execute(anyObject())).thenReturn(actionWrapperResult);
|
||||
|
||||
when(watch.actions()).thenReturn(Collections.singletonList(actionWrapper));
|
||||
|
||||
WatchStatus status = mock(WatchStatus.class);
|
||||
when(status.state()).thenReturn(new WatchStatus.State(false, now()));
|
||||
when(watch.status()).thenReturn(status);
|
||||
|
||||
WatchRecord watchRecord = executionService.execute(ctx);
|
||||
assertThat(watchRecord.state(), is(ExecutionState.EXECUTED));
|
||||
}
|
||||
|
||||
private WatchExecutionContext createMockWatchExecutionContext(String watchId, DateTime executionTime) {
|
||||
WatchExecutionContext ctx = mock(WatchExecutionContext.class);
|
||||
when(ctx.id()).thenReturn(new Wid(watchId, executionTime));
|
||||
|
|
Loading…
Reference in New Issue