Cleanup and Refactoring of the conditions

* Split the action into two constructs: `Condition` and `ExecutableCondition`. The former holds all the condition configuration, the latter can execute the condition based on that configuration (an executable condition holds a condition)
 - This the code clearer to understand and maintain.
 - This also enabled to pull some common implementation code into the `ExecutableCondition` and by that reduce the implementation details of each executable to the minimum required.

* Also, extracted the `Condition.Parser` to its own top level class, and renamed it to - `ConditionFactory`. The main thing that the factory does is: 1) delegate to the parsing to the `Condition` class, 2) construct & wire up the `ExecutableCondition`.

* With the introduction of `Condition`, we no longer need the `SourceBuilder` for conditions. Instead, we have `Condiiton.Builder` that help you build condition. This is much more intuitive from the client perspective.

* Renamed `always_true` condition type to `always`
* Renamed `always_false` condition type to `never`

* Updated docs (also added docs for the `never` condition)

Original commit: elastic/x-pack-elasticsearch@0f8eb494ca
This commit is contained in:
uboness 2015-04-14 18:27:34 -07:00
parent cce3291b59
commit f54c610c29
47 changed files with 1087 additions and 748 deletions

View File

@ -16,7 +16,7 @@ import org.elasticsearch.search.builder.SearchSourceBuilderException;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.actions.Action;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.ConditionBuilders;
import org.elasticsearch.watcher.condition.always.AlwaysCondition;
import org.elasticsearch.watcher.input.Input;
import org.elasticsearch.watcher.input.NoneInput;
import org.elasticsearch.watcher.transform.Transform;
@ -34,7 +34,7 @@ public class WatchSourceBuilder implements ToXContent {
private Trigger.SourceBuilder trigger;
private Input.SourceBuilder input = NoneInput.SourceBuilder.INSTANCE;
private Condition.SourceBuilder condition = ConditionBuilders.alwaysTrueCondition();
private Condition condition = AlwaysCondition.INSTANCE;
private Transform.SourceBuilder transform = null;
private Map<String, TransformedAction> actions = new HashMap<>();
private TimeValue throttlePeriod = null;
@ -50,7 +50,11 @@ public class WatchSourceBuilder implements ToXContent {
return this;
}
public WatchSourceBuilder condition(Condition.SourceBuilder condition) {
public WatchSourceBuilder condition(Condition.Builder condition) {
return condition(condition.build());
}
public WatchSourceBuilder condition(Condition condition) {
this.condition = condition;
return this;
}

View File

@ -5,60 +5,17 @@
*/
package org.elasticsearch.watcher.condition;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
*
*/
public abstract class Condition<R extends Condition.Result> implements ToXContent {
public interface Condition extends ToXContent {
protected static final ParseField MET_FIELD = new ParseField("met");
String type();
protected final ESLogger logger;
protected Condition(ESLogger logger) {
this.logger = logger;
}
/**
* @return the type of this condition
*/
public abstract String type();
/**
* Executes this condition
*/
public abstract R execute(WatchExecutionContext ctx) throws IOException;
/**
* Parses xcontent to a concrete condition of the same type.
*/
public static interface Parser<R extends Condition.Result, C extends Condition<R>> {
/**
* @return The type of the condition
*/
String type();
/**
* Parses the given xcontent and creates a concrete condition
*/
C parse(XContentParser parser) throws IOException;
/**
* Parses the given xContent and creates a concrete result
*/
R parseResult(XContentParser parser) throws IOException;
}
public abstract static class Result implements ToXContent {
abstract class Result implements ToXContent {
private final String type;
private final boolean met;
@ -76,9 +33,12 @@ public abstract class Condition<R extends Condition.Result> implements ToXConten
}
public static interface SourceBuilder extends ToXContent {
interface Builder<C extends Condition> {
public String type();
C build();
}
interface Field {
ParseField MET = new ParseField("met");
}
}

View File

@ -5,9 +5,12 @@
*/
package org.elasticsearch.watcher.condition;
import org.elasticsearch.watcher.condition.always.AlwaysCondition;
import org.elasticsearch.watcher.condition.never.NeverCondition;
import org.elasticsearch.watcher.condition.script.ExecutableScriptCondition;
import org.elasticsearch.watcher.condition.never.ExecutableNeverCondition;
import org.elasticsearch.watcher.condition.always.ExecutableAlwaysCondition;
import org.elasticsearch.watcher.condition.script.ScriptCondition;
import org.elasticsearch.watcher.condition.simple.AlwaysFalseCondition;
import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition;
/**
*
@ -17,20 +20,15 @@ public final class ConditionBuilders {
private ConditionBuilders() {
}
public static AlwaysTrueCondition.SourceBuilder alwaysTrueCondition() {
return AlwaysTrueCondition.SourceBuilder.INSTANCE;
public static AlwaysCondition.Builder alwaysCondition() {
return AlwaysCondition.Builder.INSTANCE;
}
public static AlwaysFalseCondition.SourceBuilder alwaysFalseCondition() {
return AlwaysFalseCondition.SourceBuilder.INSTANCE;
public static NeverCondition.Builder neverCondition() {
return NeverCondition.Builder.INSTANCE;
}
public static ScriptCondition.SourceBuilder scriptCondition() {
return new ScriptCondition.SourceBuilder();
public static ScriptCondition.Builder scriptCondition(String script) {
return ScriptCondition.builder(script);
}
public static ScriptCondition.SourceBuilder scriptCondition(String script) {
return new ScriptCondition.SourceBuilder().script(script);
}
}

View File

@ -12,11 +12,11 @@ import org.elasticsearch.watcher.WatcherException;
*/
public class ConditionException extends WatcherException {
public ConditionException(String msg) {
super(msg);
public ConditionException(String msg, Object... args) {
super(msg, args);
}
public ConditionException(String msg, Throwable cause) {
super(msg, cause);
public ConditionException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -0,0 +1,43 @@
/*
* 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.condition;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* Parses xcontent to a concrete condition of the same type.
*/
public abstract class ConditionFactory<C extends Condition, R extends Condition.Result, E extends ExecutableCondition<C, R>> {
protected final ESLogger conditionLogger;
public ConditionFactory(ESLogger conditionLogger) {
this.conditionLogger = conditionLogger;
}
/**
* @return The type of the condition
*/
public abstract String type();
/**
* Parses the given xcontent and creates a concrete condition
*/
public abstract C parseCondition(String watchId, XContentParser parser) throws IOException;
/**
* Parses the given xContent and creates a concrete result
*/
public abstract R parseResult(String watchId, XContentParser parser) throws IOException;
/**
* Creates an {@link ExecutableCondition executable condition} for the given condition.
*/
public abstract E createExecutable(C condition);
}

View File

@ -5,11 +5,14 @@
*/
package org.elasticsearch.watcher.condition;
import org.elasticsearch.watcher.condition.script.ScriptCondition;
import org.elasticsearch.watcher.condition.simple.AlwaysFalseCondition;
import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.multibindings.MapBinder;
import org.elasticsearch.watcher.condition.always.AlwaysCondition;
import org.elasticsearch.watcher.condition.always.AlwaysConditionFactory;
import org.elasticsearch.watcher.condition.never.NeverCondition;
import org.elasticsearch.watcher.condition.never.NeverConditionFactory;
import org.elasticsearch.watcher.condition.script.ScriptCondition;
import org.elasticsearch.watcher.condition.script.ScriptConditionFactory;
import java.util.HashMap;
import java.util.Map;
@ -19,26 +22,29 @@ import java.util.Map;
*/
public class ConditionModule extends AbstractModule {
private final Map<String, Class<? extends Condition.Parser>> parsers = new HashMap<>();
private final Map<String, Class<? extends ConditionFactory>> factories = new HashMap<>();
public void registerCondition(String type, Class<? extends Condition.Parser> parserType) {
parsers.put(type, parserType);
public void registerCondition(String type, Class<? extends ConditionFactory> factoryType) {
factories.put(type, factoryType);
}
@Override
protected void configure() {
MapBinder<String, Condition.Parser> parsersBinder = MapBinder.newMapBinder(binder(), String.class, Condition.Parser.class);
bind(ScriptCondition.Parser.class).asEagerSingleton();
parsersBinder.addBinding(ScriptCondition.TYPE).to(ScriptCondition.Parser.class);
bind(AlwaysFalseCondition.Parser.class).asEagerSingleton();
parsersBinder.addBinding(AlwaysFalseCondition.TYPE).to(AlwaysFalseCondition.Parser.class);
bind(AlwaysTrueCondition.Parser.class).asEagerSingleton();
parsersBinder.addBinding(AlwaysTrueCondition.TYPE).to(AlwaysTrueCondition.Parser.class);
MapBinder<String, ConditionFactory> factoriesBinder = MapBinder.newMapBinder(binder(), String.class, ConditionFactory.class);
for (Map.Entry<String, Class<? extends Condition.Parser>> entry : parsers.entrySet()) {
bind(ScriptConditionFactory.class).asEagerSingleton();
factoriesBinder.addBinding(ScriptCondition.TYPE).to(ScriptConditionFactory.class);
bind(NeverConditionFactory.class).asEagerSingleton();
factoriesBinder.addBinding(NeverCondition.TYPE).to(NeverConditionFactory.class);
bind(AlwaysConditionFactory.class).asEagerSingleton();
factoriesBinder.addBinding(AlwaysCondition.TYPE).to(AlwaysConditionFactory.class);
for (Map.Entry<String, Class<? extends ConditionFactory>> entry : factories.entrySet()) {
bind(entry.getValue()).asEagerSingleton();
parsersBinder.addBinding(entry.getKey()).to(entry.getValue());
factoriesBinder.addBinding(entry.getKey()).to(entry.getValue());
}
bind(ConditionRegistry.class).asEagerSingleton();

View File

@ -18,74 +18,99 @@ import java.util.Set;
*/
public class ConditionRegistry {
private final ImmutableMap<String, Condition.Parser> parsers;
private final ImmutableMap<String, ConditionFactory> factories;
@Inject
public ConditionRegistry(Map<String, Condition.Parser> parsers) {
this.parsers = ImmutableMap.copyOf(parsers);
public ConditionRegistry(Map<String, ConditionFactory> factories) {
this.factories = ImmutableMap.copyOf(factories);
}
public Set<String> types() {
return parsers.keySet();
return factories.keySet();
}
/**
* Reads the contents of parser to create the correct Condition
*
* @param parser The parser containing the condition definition
* @return A new condition instance from the parser
* @throws IOException
* Parses the xcontent and returns the appropriate executable condition. Expecting the following format:
* <code><pre>
* {
* "condition_type" : {
* ... //condition body
* }
* }
* </pre></code>
*/
public Condition parse(XContentParser parser) throws IOException {
public ExecutableCondition parseExecutable(String watchId, XContentParser parser) throws IOException {
Condition condition = parseCondition(watchId, parser);
return factories.get(condition.type()).createExecutable(condition);
}
/**
* Parses the xcontent and returns the appropriate condition. Expecting the following format:
* <code><pre>
* {
* "condition_type" : {
* ... //condition body
* }
* }
* </pre></code>
*/
public Condition parseCondition(String watchId, XContentParser parser) throws IOException {
Condition condition = null;
ConditionFactory factory = null;
String type = null;
XContentParser.Token token;
Condition condition = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
type = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT && type != null) {
Condition.Parser conditionParser = parsers.get(type);
if (conditionParser == null) {
throw new ConditionException("unknown condition type [" + type + "]");
} else if (type == null) {
throw new ConditionException("could not parse condition for watch [{}]. invalid definition. expected a field indicating the condition type, but found", watchId, token);
} else {
factory = factories.get(type);
if (factory == null) {
throw new ConditionException("could not parse condition for watch [{}]. unknown condition type [{}]", watchId, type);
}
condition = conditionParser.parse(parser);
} else if (token == XContentParser.Token.VALUE_STRING && type != null) {
Condition.Parser conditionParser = parsers.get(type);
if (conditionParser == null) {
throw new ConditionException("unknown condition type [" + type + "]");
}
condition = conditionParser.parse(parser);
condition = factory.parseCondition(watchId, parser);
}
}
if (condition == null) {
throw new ConditionException("failed to parse condition");
throw new ConditionException("could not parse condition for watch [{}]. missing required condition type field", watchId);
}
return condition;
}
/**
* Reads the contents of parser to create the correct Condition.Result
*
* @param parser The parser containing the condition result definition
* @return A new condition result instance from the parser
* @throws IOException
* Parses the xcontent and returns the appropriate condition result. Expecting the following format:
* <code><pre>
* {
* "condition_type" : {
* ... // result body
* }
* }
* </pre></code>
*/
public Condition.Result parseResult(XContentParser parser) throws IOException {
public Condition.Result parseResult(String watchId, XContentParser parser) throws IOException {
Condition.Result result = null;
String type = null;
XContentParser.Token token;
Condition.Result conditionResult = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
type = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT && type != null) {
Condition.Parser conditionParser = parsers.get(type);
if (conditionParser == null) {
throw new ConditionException("unknown condition type [" + type + "]");
} else if (type == null) {
throw new ConditionException("could not parse condition result for watch [{}]. invalid definition. expected a field indicating the condition type, but found", watchId, token);
} else {
ConditionFactory factory = factories.get(type);
if (factory == null) {
throw new ConditionException("could not parse condition result for watch [{}]. un known condition type [{}]", watchId, type);
}
conditionResult = conditionParser.parseResult(parser);
result = factory.parseResult(watchId, parser);
}
}
return conditionResult;
if (result == null) {
throw new ConditionException("could not parse condition result for watch [{}]. missing required condition type field", watchId);
}
return result;
}
}

View File

@ -0,0 +1,63 @@
/*
* 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.condition;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
import java.io.IOException;
/**
*
*/
public abstract class ExecutableCondition<C extends Condition, R extends Condition.Result> implements ToXContent {
protected final C condition;
protected final ESLogger logger;
protected ExecutableCondition(C condition, ESLogger logger) {
this.condition = condition;
this.logger = logger;
}
/**
* @return the type of this condition
*/
public final String type() {
return condition.type();
}
public C condition() {
return condition;
}
/**
* Executes this condition
*/
public abstract R execute(WatchExecutionContext ctx) throws IOException;
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return condition.toXContent(builder, params);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ExecutableCondition<?, ?> that = (ExecutableCondition<?, ?>) o;
return condition.equals(that.condition);
}
@Override
public int hashCode() {
return condition.hashCode();
}
}

View File

@ -0,0 +1,76 @@
/*
* 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.condition.always;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.condition.Condition;
import java.io.IOException;
/**
*
*/
public class AlwaysCondition implements Condition {
public static final String TYPE = "always";
public static final AlwaysCondition INSTANCE = new AlwaysCondition();
@Override
public final String type() {
return TYPE;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().endObject();
}
public static AlwaysCondition parse(String watchId, XContentParser parser) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
throw new AlwaysConditionException("unable to parse [{}] condition for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
}
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.END_OBJECT) {
throw new AlwaysConditionException("unable to parse [{}] condition for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
}
return INSTANCE;
}
public static class Result extends Condition.Result {
public static final Result INSTANCE = new Result();
private Result() {
super(TYPE, true);
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().endObject();
}
public static Result parse(String watchId, XContentParser parser) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
throw new AlwaysConditionException("unable to parse [{}] condition result for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
}
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.END_OBJECT) {
throw new AlwaysConditionException("unable to parse [{}] condition result for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
}
return INSTANCE;
}
}
public static class Builder implements Condition.Builder<AlwaysCondition> {
public static final Builder INSTANCE = new Builder();
public AlwaysCondition build() {
return AlwaysCondition.INSTANCE;
}
}
}

View File

@ -0,0 +1,22 @@
/*
* 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.condition.always;
import org.elasticsearch.watcher.condition.ConditionException;
/**
*
*/
public class AlwaysConditionException extends ConditionException {
public AlwaysConditionException(String msg, Object... args) {
super(msg, args);
}
public AlwaysConditionException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -0,0 +1,48 @@
/*
* 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.condition.always;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.condition.ConditionFactory;
import java.io.IOException;
/**
*
*/
public class AlwaysConditionFactory extends ConditionFactory<AlwaysCondition, AlwaysCondition.Result, ExecutableAlwaysCondition> {
private final ExecutableAlwaysCondition condition;
@Inject
public AlwaysConditionFactory(Settings settings) {
super(Loggers.getLogger(ExecutableAlwaysCondition.class, settings));
condition = new ExecutableAlwaysCondition(conditionLogger);
}
@Override
public String type() {
return AlwaysCondition.TYPE;
}
@Override
public AlwaysCondition parseCondition(String watchId, XContentParser parser) throws IOException {
return AlwaysCondition.parse(watchId, parser);
}
@Override
public AlwaysCondition.Result parseResult(String watchId, XContentParser parser) throws IOException {
return AlwaysCondition.Result.parse(watchId, parser);
}
@Override
public ExecutableAlwaysCondition createExecutable(AlwaysCondition condition) {
return this.condition;
}
}

View File

@ -0,0 +1,38 @@
/*
* 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.condition.always;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.watcher.condition.ExecutableCondition;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
import java.io.IOException;
/**
*/
public class ExecutableAlwaysCondition extends ExecutableCondition<AlwaysCondition, AlwaysCondition.Result> {
public ExecutableAlwaysCondition(ESLogger logger) {
super(AlwaysCondition.INSTANCE, logger);
}
@Override
public AlwaysCondition.Result execute(WatchExecutionContext ctx) throws IOException {
return AlwaysCondition.Result.INSTANCE;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().endObject();
}
@Override
public boolean equals(Object obj) {
return obj instanceof ExecutableAlwaysCondition;
}
}

View File

@ -0,0 +1,38 @@
/*
* 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.condition.never;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.watcher.condition.ExecutableCondition;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
import java.io.IOException;
/**
*/
public class ExecutableNeverCondition extends ExecutableCondition<NeverCondition, NeverCondition.Result> {
public ExecutableNeverCondition(ESLogger logger) {
super(NeverCondition.INSTANCE, logger);
}
@Override
public NeverCondition.Result execute(WatchExecutionContext ctx) throws IOException {
return NeverCondition.Result.INSTANCE;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().endObject();
}
@Override
public boolean equals(Object obj) {
return obj instanceof ExecutableNeverCondition;
}
}

View File

@ -0,0 +1,76 @@
/*
* 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.condition.never;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.condition.Condition;
import java.io.IOException;
/**
*
*/
public class NeverCondition implements Condition {
public static final String TYPE = "never";
public static final NeverCondition INSTANCE = new NeverCondition();
@Override
public final String type() {
return TYPE;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().endObject();
}
public static NeverCondition parse(String watchId, XContentParser parser) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
throw new NeverConditionException("could not parse [{}] condition for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
}
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.END_OBJECT) {
throw new NeverConditionException("could not parse [{}] condition for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
}
return INSTANCE;
}
public static class Result extends Condition.Result {
public static final Result INSTANCE = new Result();
private Result() {
super(TYPE, false);
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().endObject();
}
public static Result parse(String watchId, XContentParser parser) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
throw new NeverConditionException("could not parse [{}] condition result for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
}
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.END_OBJECT) {
throw new NeverConditionException("could not parse [{}] condition result for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
}
return INSTANCE;
}
}
public static class Builder implements Condition.Builder<NeverCondition> {
public static final Builder INSTANCE = new Builder();
public NeverCondition build() {
return NeverCondition.INSTANCE;
}
}
}

View File

@ -0,0 +1,22 @@
/*
* 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.condition.never;
import org.elasticsearch.watcher.condition.ConditionException;
/**
*
*/
public class NeverConditionException extends ConditionException {
public NeverConditionException(String msg, Object... args) {
super(msg, args);
}
public NeverConditionException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -0,0 +1,48 @@
/*
* 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.condition.never;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.condition.ConditionFactory;
import java.io.IOException;
/**
*
*/
public class NeverConditionFactory extends ConditionFactory<NeverCondition, NeverCondition.Result, ExecutableNeverCondition> {
private final ExecutableNeverCondition condition;
@Inject
public NeverConditionFactory(Settings settings) {
super(Loggers.getLogger(ExecutableNeverCondition.class, settings));
condition = new ExecutableNeverCondition(conditionLogger);
}
@Override
public String type() {
return NeverCondition.TYPE;
}
@Override
public NeverCondition parseCondition(String watchId, XContentParser parser) throws IOException {
return NeverCondition.parse(watchId, parser);
}
@Override
public NeverCondition.Result parseResult(String watchId, XContentParser parser) throws IOException {
return NeverCondition.Result.parse(watchId, parser);
}
@Override
public ExecutableNeverCondition createExecutable(NeverCondition condition) {
return this.condition;
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.condition.script;
import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.script.ExecutableScript;
import org.elasticsearch.watcher.condition.ConditionException;
import org.elasticsearch.watcher.condition.ExecutableCondition;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
import org.elasticsearch.watcher.support.Variables;
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
import java.io.IOException;
/**
* This class executes a script against the ctx payload and returns a boolean
*/
public class ExecutableScriptCondition extends ExecutableCondition<ScriptCondition, ScriptCondition.Result> {
private final ScriptServiceProxy scriptService;
public ExecutableScriptCondition(ScriptCondition condition, ESLogger logger, ScriptServiceProxy scriptService) {
super(condition, logger);
this.scriptService = scriptService;
}
@Override
public ScriptCondition.Result execute(WatchExecutionContext ctx) throws IOException {
ExecutableScript executable = scriptService.executable(condition.script, Variables.createCtxModel(ctx, ctx.payload()));
Object value = executable.run();
if (value instanceof Boolean) {
return (Boolean) value ? ScriptCondition.Result.MET : ScriptCondition.Result.UNMET;
}
throw new ConditionException("failed to execute [{}] condition for watch [{}]. script [{}] must return a boolean value (true|false) but instead returned [{}]", type(), ctx.watch().name(), condition.script.script(), value);
}
}

View File

@ -5,66 +5,38 @@
*/
package org.elasticsearch.watcher.condition.script;
import org.elasticsearch.watcher.WatcherSettingsException;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.ConditionException;
import org.elasticsearch.watcher.support.Script;
import org.elasticsearch.watcher.support.Variables;
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.script.ExecutableScript;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.support.Script;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
/**
* This class executes a script against the ctx payload and returns a boolean
*
*/
public class ScriptCondition extends Condition<ScriptCondition.Result> {
public class ScriptCondition implements Condition {
public static final String TYPE = "script";
private final ScriptServiceProxy scriptService;
private final Script script;
final Script script;
public ScriptCondition(ESLogger logger, ScriptServiceProxy scriptService, Script script) {
super(logger);
this.scriptService = scriptService;
public ScriptCondition(Script script) {
this.script = script;
}
@Override
public String type() {
public final String type() {
return TYPE;
}
public Script script() {
public Script getScript() {
return script;
}
@Override
public Result execute(WatchExecutionContext ctx) throws IOException {
ImmutableMap<String, Object> model = ImmutableMap.<String, Object>builder()
.putAll(script.params())
.putAll(Variables.createCtxModel(ctx, ctx.payload()))
.build();
ExecutableScript executable = scriptService.executable(script.lang(), script.script(), script.type(), model);
Object value = executable.run();
if (value instanceof Boolean) {
return (Boolean) value ? Result.MET : Result.UNMET;
}
throw new ConditionException("condition script [" + script + "] did not return a boolean value");
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return script.toXContent(builder, params);
@ -75,11 +47,9 @@ public class ScriptCondition extends Condition<ScriptCondition.Result> {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ScriptCondition that = (ScriptCondition) o;
ScriptCondition condition = (ScriptCondition) o;
if (!script.equals(that.script)) return false;
return true;
return script.equals(condition.script);
}
@Override
@ -87,59 +57,17 @@ public class ScriptCondition extends Condition<ScriptCondition.Result> {
return script.hashCode();
}
public static class Parser extends AbstractComponent implements Condition.Parser<Result, ScriptCondition> {
private final ScriptServiceProxy scriptService;
@Inject
public Parser(Settings settings, ScriptServiceProxy service) {
super(settings);
scriptService = service;
public static ScriptCondition parse(String watchId, XContentParser parser) throws IOException {
try {
Script script = Script.parse(parser);
return new ScriptCondition(script);
} catch (Script.ParseException pe) {
throw new ScriptConditionException("could not parse [{}] condition for watch [{}]. failed to parse script", pe, TYPE, watchId);
}
}
@Override
public String type() {
return TYPE;
}
@Override
public ScriptCondition parse(XContentParser parser) throws IOException {
try {
Script script = Script.parse(parser);
return new ScriptCondition(logger, scriptService, script);
} catch (Script.ParseException pe) {
throw new WatcherSettingsException("could not parse [script] condition", pe);
}
}
@Override
public Result parseResult(XContentParser parser) throws IOException {
Boolean met = null;
String currentFieldName = null;
XContentParser.Token token;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token.isValue()) {
if (token == XContentParser.Token.VALUE_BOOLEAN) {
if (Condition.MET_FIELD.match(currentFieldName)) {
met = parser.booleanValue();
} else {
throw new ConditionException("unable to parse [script] condition result. expected a boolean, got [" + parser.text() + "]");
}
} else {
throw new ConditionException("unable to parse [script] condition result. unexpected field [" + currentFieldName + "]");
}
}
}
if (met == null) {
throw new ConditionException("could not parse [script] condition result. [met] is a required field");
}
return met ? Result.MET : Result.UNMET;
}
public static Builder builder(String script) {
return new Builder(script);
}
public static class Result extends Condition.Result {
@ -154,46 +82,71 @@ public class ScriptCondition extends Condition<ScriptCondition.Result> {
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject()
.field(MET_FIELD.getPreferredName(), met())
.field(Field.MET.getPreferredName(), met())
.endObject();
}
public static Result parse(String watchId, XContentParser parser) throws IOException {
Boolean met = null;
String currentFieldName = null;
XContentParser.Token token;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.VALUE_BOOLEAN) {
if (Field.MET.match(currentFieldName)) {
met = parser.booleanValue();
} else {
throw new ScriptConditionException("could not parse [{}] condition result for watch [{}]. unexpected boolean field [{}]", TYPE, watchId, currentFieldName);
}
} else {
throw new ScriptConditionException("could not parse [{}] condition result for watch [{}]. unexpected token [{}]", TYPE, watchId, token);
}
}
if (met == null) {
throw new ScriptConditionException("could not parse [{}] condition result for watch [{}]. missing required [{}] field", TYPE, watchId, Field.MET.getPreferredName());
}
return met ? ScriptCondition.Result.MET : ScriptCondition.Result.UNMET;
}
}
public static class SourceBuilder implements Condition.SourceBuilder {
public static class Builder implements Condition.Builder<ScriptCondition> {
private String script;
private String lang = ScriptService.DEFAULT_LANG;
private ScriptService.ScriptType type = ScriptService.ScriptType.INLINE;
private Map<String, Object> params = Collections.emptyMap();
private final String script;
private ScriptService.ScriptType type = Script.DEFAULT_TYPE;
private String lang = Script.DEFAULT_LANG;
private ImmutableMap.Builder<String, Object> vars = ImmutableMap.builder();
public SourceBuilder script(String script) {
private Builder(String script) {
this.script = script;
return this;
}
public SourceBuilder lang(String lang) {
this.lang = lang;
return this;
}
public SourceBuilder type(ScriptService.ScriptType type) {
public Builder setType(ScriptService.ScriptType type) {
this.type = type;
return this;
}
public SourceBuilder type(Map<String, Object> params) {
this.params = params;
public Builder setLang(String lang) {
this.lang = lang;
return this;
}
public Builder addVars(Map<String, Object> vars) {
this.vars.putAll(vars);
return this;
}
public Builder setVar(String name, Object value) {
this.vars.put(name, value);
return this;
}
@Override
public String type() {
return TYPE;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return new Script(script, type, lang, this.params).toXContent(builder, params);
public ScriptCondition build() {
return new ScriptCondition(new Script(this.script, type, lang, vars.build()));
}
}
}

View File

@ -0,0 +1,22 @@
/*
* 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.condition.script;
import org.elasticsearch.watcher.condition.ConditionException;
/**
*
*/
public class ScriptConditionException extends ConditionException {
public ScriptConditionException(String msg, Object... args) {
super(msg, args);
}
public ScriptConditionException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -0,0 +1,49 @@
/*
* 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.condition.script;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.condition.ConditionFactory;
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
import java.io.IOException;
/**
*
*/
public class ScriptConditionFactory extends ConditionFactory<ScriptCondition, ScriptCondition.Result, ExecutableScriptCondition> {
private final ScriptServiceProxy scriptService;
@Inject
public ScriptConditionFactory(Settings settings, ScriptServiceProxy service) {
super(Loggers.getLogger(ExecutableScriptCondition.class, settings));
scriptService = service;
}
@Override
public String type() {
return ScriptCondition.TYPE;
}
@Override
public ScriptCondition parseCondition(String watchId, XContentParser parser) throws IOException {
return ScriptCondition.parse(watchId, parser);
}
@Override
public ScriptCondition.Result parseResult(String watchId, XContentParser parser) throws IOException {
return ScriptCondition.Result.parse(watchId, parser);
}
@Override
public ExecutableScriptCondition createExecutable(ScriptCondition condition) {
return new ExecutableScriptCondition(condition, conditionLogger, scriptService);
}
}

View File

@ -1,114 +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.condition.simple;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.ConditionException;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
*/
public class AlwaysFalseCondition extends Condition<Condition.Result> {
public static final String TYPE = "always_false";
public static final Result RESULT = new Result(TYPE, false) {
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().endObject();
}
};
public AlwaysFalseCondition(ESLogger logger) {
super(logger);
}
@Override
public String type() {
return TYPE;
}
@Override
public Result execute(WatchExecutionContext ctx) throws IOException {
return RESULT;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().endObject();
}
@Override
public boolean equals(Object obj) {
return obj instanceof AlwaysFalseCondition;
}
public static class Parser extends AbstractComponent implements Condition.Parser<Result, AlwaysFalseCondition> {
@Inject
public Parser(Settings settings) {
super(settings);
}
@Override
public String type() {
return TYPE;
}
@Override
public AlwaysFalseCondition parse(XContentParser parser) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_OBJECT){
throw new ConditionException("unable to parse [" + TYPE + "] condition. expected a start object token, found [" + parser.currentToken() + "]");
}
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.END_OBJECT) {
throw new ConditionException("unable to parse [" + TYPE + "] condition. expected an empty object, but found an object with [" + token + "]");
}
return new AlwaysFalseCondition(logger);
}
@Override
public Result parseResult(XContentParser parser) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_OBJECT){
throw new ConditionException("unable to parse [" + TYPE + "] condition result. expected a start object token, found [" + parser.currentToken() + "]");
}
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.END_OBJECT) {
throw new ConditionException("unable to parse [" + TYPE + "] condition result. expected an empty object, but found an object with [" + token + "]");
}
return RESULT;
}
}
public static class SourceBuilder implements Condition.SourceBuilder {
public static final SourceBuilder INSTANCE = new SourceBuilder();
public SourceBuilder() {
}
@Override
public String type() {
return TYPE;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().endObject();
}
}
}

View File

@ -1,112 +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.condition.simple;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.ConditionException;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
*/
public class AlwaysTrueCondition extends Condition<Condition.Result> {
public static final String TYPE = "always_true";
public static final Result RESULT = new Result(TYPE, true) {
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().endObject();
}
};
public AlwaysTrueCondition(ESLogger logger) {
super(logger);
}
@Override
public String type() {
return TYPE;
}
@Override
public Result execute(WatchExecutionContext ctx) throws IOException {
return RESULT;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().endObject();
}
@Override
public boolean equals(Object obj) {
return obj instanceof AlwaysTrueCondition;
}
public static class Parser extends AbstractComponent implements Condition.Parser<Result, AlwaysTrueCondition> {
@Inject
public Parser(Settings settings) {
super(settings);
}
@Override
public String type() {
return TYPE;
}
@Override
public AlwaysTrueCondition parse(XContentParser parser) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_OBJECT){
throw new ConditionException("unable to parse [" + TYPE + "] condition. expected a start object token, found [" + parser.currentToken() + "]");
}
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.END_OBJECT) {
throw new ConditionException("unable to parse [" + TYPE + "] condition. expected an empty object, but found an object with [" + token + "]");
}
return new AlwaysTrueCondition(logger);
}
@Override
public Result parseResult(XContentParser parser) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_OBJECT){
throw new ConditionException("unable to parse [" + TYPE + "] condition result. expected a start object token, found [" + parser.currentToken() + "]");
}
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.END_OBJECT) {
throw new ConditionException("unable to parse [" + TYPE + "] condition. expected an empty object, but found an object with [" + token + "]");
}
return RESULT;
}
}
public static class SourceBuilder implements Condition.SourceBuilder {
public static final SourceBuilder INSTANCE = new SourceBuilder();
public SourceBuilder() {
}
@Override
public String type() {
return TYPE;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().endObject();
}
}
}

View File

@ -9,6 +9,7 @@ import org.elasticsearch.common.joda.time.DateTime;
import org.elasticsearch.watcher.actions.ExecutableActions;
import org.elasticsearch.watcher.actions.ActionWrapper;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.ExecutableCondition;
import org.elasticsearch.watcher.input.Input;
import org.elasticsearch.watcher.throttle.Throttler;
import org.elasticsearch.watcher.transform.Transform;

View File

@ -60,7 +60,7 @@ public class WatchRecord implements ToXContent {
this.id = id;
this.name = watch.name();
this.triggerEvent = triggerEvent;
this.condition = watch.condition();
this.condition = watch.condition().condition();
this.input = watch.input();
this.state = State.AWAITS_EXECUTION;
this.metadata = watch.metadata();
@ -250,7 +250,7 @@ public class WatchRecord implements ToXContent {
if (Watch.Parser.INPUT_FIELD.match(currentFieldName)) {
record.input = inputRegistry.parse(parser);
} else if (Watch.Parser.CONDITION_FIELD.match(currentFieldName)) {
record.condition = conditionRegistry.parse(parser);
record.condition = conditionRegistry.parseCondition(id, parser);
} else if (METADATA_FIELD.match(currentFieldName)) {
record.metadata = parser.map();
} else if (WATCH_EXECUTION_FIELD.match(currentFieldName)) {

View File

@ -22,6 +22,9 @@ import java.util.Map;
*/
public class Script implements ToXContent {
public static final ScriptService.ScriptType DEFAULT_TYPE = ScriptService.ScriptType.INLINE;
public static final String DEFAULT_LANG = ScriptService.DEFAULT_LANG;
public static final ParseField SCRIPT_FIELD = new ParseField("script");
public static final ParseField TYPE_FIELD = new ParseField("type");
public static final ParseField LANG_FIELD = new ParseField("lang");
@ -33,7 +36,7 @@ public class Script implements ToXContent {
private final Map<String, Object> params;
public Script(String script) {
this(script, ScriptService.ScriptType.INLINE, ScriptService.DEFAULT_LANG, Collections.<String, Object>emptyMap());
this(script, DEFAULT_TYPE, DEFAULT_LANG, Collections.<String, Object>emptyMap());
}
public Script(String script, ScriptService.ScriptType type, String lang) {

View File

@ -5,11 +5,14 @@
*/
package org.elasticsearch.watcher.support.init.proxy;
import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.inject.Injector;
import org.elasticsearch.script.ExecutableScript;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.SearchScript;
import org.elasticsearch.search.lookup.SearchLookup;
import org.elasticsearch.watcher.support.Script;
import org.elasticsearch.watcher.support.Variables;
import org.elasticsearch.watcher.support.init.InitializingService;
import java.util.Map;
@ -36,6 +39,16 @@ public class ScriptServiceProxy implements InitializingService.Initializable {
this.service = injector.getInstance(ScriptService.class);
}
public ExecutableScript executable(Script script, Map<String, Object> vars) {
if (script.params() != null && !script.params().isEmpty()) {
vars = ImmutableMap.<String, Object>builder()
.putAll(script.params())
.putAll(vars)
.build();
}
return executable(script.lang(), script.script(), script.type(), vars);
}
public ExecutableScript executable(String lang, String script, ScriptService.ScriptType scriptType, Map<String, Object> vars) {
return service.executable(lang, script, scriptType, vars);
}

View File

@ -21,7 +21,7 @@ import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition;
import org.elasticsearch.watcher.condition.always.AlwaysCondition;
import org.elasticsearch.watcher.execution.ExecutionService;
import org.elasticsearch.watcher.execution.ManualExecutionContext;
import org.elasticsearch.watcher.history.WatchRecord;
@ -94,7 +94,7 @@ public class TransportExecuteWatchAction extends WatcherTransportAction<ExecuteW
ctxBuilder.withInput(new SimpleInput.Result(new Payload.Simple(request.getAlternativeInput())));
}
if (request.isIgnoreCondition()) {
ctxBuilder.withCondition(AlwaysTrueCondition.RESULT);
ctxBuilder.withCondition(AlwaysCondition.Result.INSTANCE);
}
if (request.isIgnoreThrottle()) {
ctxBuilder.withThrottle(Throttler.Result.NO);

View File

@ -25,9 +25,9 @@ import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.WatcherSettingsException;
import org.elasticsearch.watcher.actions.ActionRegistry;
import org.elasticsearch.watcher.actions.ExecutableActions;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.ExecutableCondition;
import org.elasticsearch.watcher.condition.ConditionRegistry;
import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition;
import org.elasticsearch.watcher.condition.always.ExecutableAlwaysCondition;
import org.elasticsearch.watcher.input.Input;
import org.elasticsearch.watcher.input.InputRegistry;
import org.elasticsearch.watcher.input.NoneInput;
@ -57,7 +57,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
private final String name;
private final Trigger trigger;
private final Input input;
private final Condition condition;
private final ExecutableCondition condition;
private final ExecutableActions actions;
private final Throttler throttler;
private final Status status;
@ -71,7 +71,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
private final transient AtomicLong nonceCounter = new AtomicLong();
public Watch(String name, Clock clock, LicenseService licenseService, Trigger trigger, Input input, Condition condition, @Nullable Transform transform,
public Watch(String name, Clock clock, LicenseService licenseService, Trigger trigger, Input input, ExecutableCondition condition, @Nullable Transform transform,
ExecutableActions actions, @Nullable Map<String, Object> metadata, @Nullable TimeValue throttlePeriod, @Nullable Status status) {
this.name = name;
this.trigger = trigger;
@ -95,7 +95,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
public Input input() { return input;}
public Condition condition() {
public ExecutableCondition condition() {
return condition;
}
@ -196,7 +196,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
private final Clock clock;
private final Input defaultInput;
private final Condition defaultCondition;
private final ExecutableCondition defaultCondition;
private final TimeValue defaultThrottleTimePeriod;
@Inject
@ -214,7 +214,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
this.clock = clock;
this.defaultInput = new NoneInput(logger);
this.defaultCondition = new AlwaysTrueCondition(logger);
this.defaultCondition = new ExecutableAlwaysCondition(logger);
this.defaultThrottleTimePeriod = settings.getAsTime(DEFAULT_THROTTLE_PERIOD_SETTING, DEFAULT_THROTTLE_PERIOD);
}
@ -232,7 +232,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
public Watch parse(String id, boolean includeStatus, XContentParser parser) throws IOException {
Trigger trigger = null;
Input input = defaultInput;
Condition condition = defaultCondition;
ExecutableCondition condition = defaultCondition;
ExecutableActions actions = null;
Transform transform = null;
Map<String, Object> metatdata = null;
@ -252,7 +252,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
} else if (INPUT_FIELD.match(currentFieldName)) {
input = inputRegistry.parse(parser);
} else if (CONDITION_FIELD.match(currentFieldName)) {
condition = conditionRegistry.parse(parser);
condition = conditionRegistry.parseExecutable(id, parser);
} else if (ACTIONS_FIELD.match(currentFieldName)) {
actions = actionRegistry.parseActions(id, parser);
} else if (TRANSFORM_FIELD.match(currentFieldName)) {

View File

@ -12,8 +12,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.actions.ActionRegistry;
import org.elasticsearch.watcher.actions.ExecutableActions;
import org.elasticsearch.watcher.actions.ActionWrapper;
import org.elasticsearch.watcher.actions.ExecutableActions;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.ConditionRegistry;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
@ -130,7 +130,7 @@ public class WatchExecution implements ToXContent {
if (INPUT_RESULT_FIELD.match(currentFieldName)) {
inputResult = inputRegistry.parseResult(parser);
} else if (CONDITION_RESULT_FIELD.match(currentFieldName)) {
conditionResult = conditionRegistry.parseResult(parser);
conditionResult = conditionRegistry.parseResult(wid.watchId(), parser);
} else if (Transform.Parser.TRANSFORM_RESULT_FIELD.match(currentFieldName)) {
transformResult = transformRegistry.parseResult(parser);
} else if (ACTIONS_RESULTS.match(currentFieldName)) {

View File

@ -0,0 +1,91 @@
/*
* 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.condition.always;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.test.ElasticsearchTestCase;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.ConditionException;
import org.elasticsearch.watcher.condition.ConditionFactory;
import org.elasticsearch.watcher.condition.ExecutableCondition;
import org.elasticsearch.watcher.condition.always.AlwaysCondition;
import org.elasticsearch.watcher.condition.always.AlwaysConditionException;
import org.elasticsearch.watcher.condition.always.AlwaysConditionFactory;
import org.elasticsearch.watcher.condition.always.ExecutableAlwaysCondition;
import org.junit.Test;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
/**
*/
public class AlwaysConditionTests extends ElasticsearchTestCase {
@Test
public void testExecute() throws Exception {
ExecutableCondition alwaysTrue = new ExecutableAlwaysCondition(logger);
assertTrue(alwaysTrue.execute(null).met());
}
@Test
public void testParser_Valid() throws Exception {
AlwaysConditionFactory factory = new AlwaysConditionFactory(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.endObject();
XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
parser.nextToken();
AlwaysCondition condition = factory.parseCondition("_id", parser);
ExecutableAlwaysCondition executable = factory.createExecutable(condition);
assertTrue(executable.execute(null).met());
}
@Test(expected = AlwaysConditionException.class)
public void testParser_Invalid() throws Exception {
ConditionFactory factor = new AlwaysConditionFactory(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder()
.startObject()
.field("foo", "bar")
.endObject();
XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
parser.nextToken();
factor.parseCondition("_id", parser);
fail("expected a condition exception trying to parse an invalid condition XContent, ["
+ AlwaysCondition.TYPE + "] condition should not parse with a body");
}
@Test
public void testResultParser_Valid() throws Exception {
ConditionFactory factory = new AlwaysConditionFactory(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.endObject();
XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
parser.nextToken();
Condition.Result alwaysTrueResult = factory.parseResult("_id", parser);
assertTrue(alwaysTrueResult.met());
}
@Test(expected = AlwaysConditionException.class)
public void testResultParser_Invalid() throws Exception {
ConditionFactory factory = new AlwaysConditionFactory(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.field("met", false);
builder.endObject();
XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
parser.nextToken();
factory.parseResult("_id", parser);
fail("expected a condition exception trying to parse an invalid condition result XContent, ["
+ AlwaysCondition.TYPE + "] condition result should not parse with a [met] field");
}
}

View File

@ -0,0 +1,94 @@
/*
* 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.condition.never;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.test.ElasticsearchTestCase;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.ConditionFactory;
import org.elasticsearch.watcher.condition.ExecutableCondition;
import org.elasticsearch.watcher.condition.always.AlwaysCondition;
import org.elasticsearch.watcher.condition.always.AlwaysConditionException;
import org.elasticsearch.watcher.condition.always.AlwaysConditionFactory;
import org.elasticsearch.watcher.condition.never.ExecutableNeverCondition;
import org.elasticsearch.watcher.condition.never.NeverCondition;
import org.elasticsearch.watcher.condition.never.NeverConditionException;
import org.elasticsearch.watcher.condition.never.NeverConditionFactory;
import org.junit.Test;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
/**
*/
public class NeverConditionTests extends ElasticsearchTestCase {
@Test
public void testExecute() throws Exception {
ExecutableCondition executable = new ExecutableNeverCondition(logger);
assertFalse(executable.execute(null).met());
}
@Test
public void testParser_Valid() throws Exception {
NeverConditionFactory factory = new NeverConditionFactory(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.endObject();
XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
parser.nextToken();
NeverCondition condition = factory.parseCondition("_id", parser);
ExecutableNeverCondition executable = factory.createExecutable(condition);
assertFalse(executable.execute(null).met());
}
@Test(expected = NeverConditionException.class)
public void testParser_Invalid() throws Exception {
ConditionFactory factory = new NeverConditionFactory(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.field("foo", "bar");
builder.endObject();
XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
parser.nextToken();
factory.parseCondition("_id", parser);
fail("expected a condition exception trying to parse an invalid condition XContent, ["
+ AlwaysCondition.TYPE + "] condition should not parse with a body");
}
@Test
public void testResultParser_Valid() throws Exception {
ConditionFactory factory = new NeverConditionFactory(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.endObject();
XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
parser.nextToken();
Condition.Result result = factory.parseResult("_id", parser);
assertFalse(result.met());
}
@Test(expected = NeverConditionException.class)
public void testResultParser_Invalid() throws Exception {
ConditionFactory factory = new NeverConditionFactory(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.field("met", false);
builder.endObject();
XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
parser.nextToken();
factory.parseResult("_id", parser);
fail("expected a condition exception trying to parse an invalid condition result XContent, ["
+ NeverCondition.TYPE + "] condition result should not parse with a [met] field");
}
}

View File

@ -31,7 +31,6 @@ import org.elasticsearch.watcher.watch.Payload;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import java.util.HashSet;
@ -83,7 +82,7 @@ public class ScriptConditionSearchTests extends AbstractWatcherIntegrationTests
.addAggregation(AggregationBuilders.dateHistogram("rate").field("_timestamp").interval(DateHistogram.Interval.HOUR).order(Histogram.Order.COUNT_DESC))
.get();
ScriptCondition condition = new ScriptCondition(logger, scriptService, new Script("ctx.payload.aggregations.rate.buckets[0]?.doc_count >= 5"));
ExecutableScriptCondition condition = new ExecutableScriptCondition(new ScriptCondition(new Script("ctx.payload.aggregations.rate.buckets[0]?.doc_count >= 5")), logger, scriptService);
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
assertFalse(condition.execute(ctx).met());
@ -101,7 +100,7 @@ public class ScriptConditionSearchTests extends AbstractWatcherIntegrationTests
@Test
public void testExecute_accessHits() throws Exception {
ScriptCondition condition = new ScriptCondition(logger, scriptService, new Script("ctx.payload.hits?.hits[0]?._score == 1.0"));
ExecutableScriptCondition condition = new ExecutableScriptCondition(new ScriptCondition(new Script("ctx.payload.hits?.hits[0]?._score == 1.0")), logger, scriptService);
InternalSearchHit hit = new InternalSearchHit(0, "1", new StringText("type"), null);
hit.score(1f);
hit.shard(new SearchShardTarget("a", "a", 0));

View File

@ -14,6 +14,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.env.Environment;
import org.elasticsearch.node.settings.NodeSettingsService;
import org.elasticsearch.script.ScriptEngineService;
@ -23,8 +24,6 @@ import org.elasticsearch.search.internal.InternalSearchResponse;
import org.elasticsearch.test.ElasticsearchTestCase;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.watcher.ResourceWatcherService;
import org.elasticsearch.watcher.WatcherSettingsException;
import org.elasticsearch.watcher.condition.ConditionException;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
import org.elasticsearch.watcher.support.Script;
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
@ -60,7 +59,7 @@ public class ScriptConditionTests extends ElasticsearchTestCase {
@Test
public void testExecute() throws Exception {
ScriptServiceProxy scriptService = getScriptServiceProxy(tp);
ScriptCondition condition = new ScriptCondition(logger, scriptService, new Script("ctx.payload.hits.total > 1"));
ExecutableScriptCondition condition = new ExecutableScriptCondition(new ScriptCondition(new Script("ctx.payload.hits.total > 1")), logger, scriptService);
SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500l, new ShardSearchFailure[0]);
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
assertFalse(condition.execute(ctx).met());
@ -70,16 +69,16 @@ public class ScriptConditionTests extends ElasticsearchTestCase {
public void testExecute_MergedParams() throws Exception {
ScriptServiceProxy scriptService = getScriptServiceProxy(tp);
Script script = new Script("ctx.payload.hits.total > threshold", ScriptService.ScriptType.INLINE, ScriptService.DEFAULT_LANG, ImmutableMap.<String, Object>of("threshold", 1));
ScriptCondition condition = new ScriptCondition(logger, scriptService, script);
ExecutableScriptCondition executable = new ExecutableScriptCondition(new ScriptCondition(script), logger, scriptService);
SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500l, new ShardSearchFailure[0]);
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
assertFalse(condition.execute(ctx).met());
assertFalse(executable.execute(ctx).met());
}
@Test
@Repeat(iterations = 5)
public void testParser_Valid() throws Exception {
ScriptCondition.Parser conditionParser = new ScriptCondition.Parser(ImmutableSettings.settingsBuilder().build(), getScriptServiceProxy(tp));
ScriptConditionFactory factory = new ScriptConditionFactory(ImmutableSettings.settingsBuilder().build(), getScriptServiceProxy(tp));
XContentBuilder builder;
if (randomBoolean()) {
@ -95,69 +94,71 @@ public class ScriptConditionTests extends ElasticsearchTestCase {
XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
parser.nextToken();
ScriptCondition condition = conditionParser.parse(parser);
ScriptCondition condition = factory.parseCondition("_watch", parser);
ExecutableScriptCondition executable = factory.createExecutable(condition);
SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500l, new ShardSearchFailure[0]);
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
assertFalse(condition.execute(ctx).met());
assertFalse(executable.execute(ctx).met());
builder = createConditionContent("return true", null, null);
parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
parser.nextToken();
condition = conditionParser.parse(parser);
condition = factory.parseCondition("_watch", parser);
executable = factory.createExecutable(condition);
ctx = mockExecutionContext("_name", new Payload.XContent(response));
assertTrue(condition.execute(ctx).met());
assertTrue(executable.execute(ctx).met());
}
@Test(expected = WatcherSettingsException.class)
@Test(expected = ScriptConditionException.class)
public void testParser_InValid() throws Exception {
ScriptCondition.Parser conditionParser = new ScriptCondition.Parser(ImmutableSettings.settingsBuilder().build(), getScriptServiceProxy(tp));
ScriptConditionFactory factory = new ScriptConditionFactory(ImmutableSettings.settingsBuilder().build(), getScriptServiceProxy(tp));
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject().endObject();
XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
parser.nextToken();
conditionParser.parse(parser);
factory.parseCondition("_id", parser);
fail("expected a condition exception trying to parse an invalid condition XContent");
}
@Test
public void testScriptResultParser_Valid() throws Exception {
ScriptCondition.Parser conditionParser = new ScriptCondition.Parser(ImmutableSettings.settingsBuilder().build(), getScriptServiceProxy(tp));
ScriptConditionFactory conditionParser = new ScriptConditionFactory(ImmutableSettings.settingsBuilder().build(), getScriptServiceProxy(tp));
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.field("met", true );
builder.field("met", true);
builder.endObject();
ScriptCondition.Result scriptResult = conditionParser.parseResult(XContentFactory.xContent(builder.bytes()).createParser(builder.bytes()));
XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes());
parser.nextToken();
ScriptCondition.Result scriptResult = conditionParser.parseResult("_id", parser);
assertTrue(scriptResult.met());
builder = jsonBuilder();
builder.startObject();
builder.field("met", false );
builder.field("met", false);
builder.endObject();
scriptResult = conditionParser.parseResult(XContentFactory.xContent(builder.bytes()).createParser(builder.bytes()));
parser = JsonXContent.jsonXContent.createParser(builder.bytes());
parser.nextToken();
scriptResult = conditionParser.parseResult("_id", parser);
assertFalse(scriptResult.met());
}
@Test(expected = ConditionException.class)
@Test(expected = ScriptConditionException.class)
public void testScriptResultParser_Invalid() throws Exception {
ScriptCondition.Parser conditionParser = new ScriptCondition.Parser(ImmutableSettings.settingsBuilder().build(), getScriptServiceProxy(tp));
ScriptConditionFactory conditionParser = new ScriptConditionFactory(ImmutableSettings.settingsBuilder().build(), getScriptServiceProxy(tp));
XContentBuilder builder = jsonBuilder();
builder.startObject().endObject();
try {
conditionParser.parseResult(XContentFactory.xContent(builder.bytes()).createParser(builder.bytes()));
} catch (Throwable t) {
throw t;
}
conditionParser.parseResult("_id", XContentFactory.xContent(builder.bytes()).createParser(builder.bytes()));
fail("expected a condition exception trying to parse an invalid condition XContent");
}

View File

@ -1,86 +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.condition.simple;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.ConditionException;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.test.ElasticsearchTestCase;
import org.junit.Test;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
/**
*/
public class AlwaysFalseConditionTests extends ElasticsearchTestCase {
@Test
public void testExecute() throws Exception {
Condition alwaysTrue = new AlwaysTrueCondition(logger);
assertTrue(alwaysTrue.execute(null).met());
}
@Test
public void testParser_Valid() throws Exception {
Condition.Parser p = new AlwaysTrueCondition.Parser(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.endObject();
XContentParser xp = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
xp.nextToken();
Condition alwaysTrue = p.parse(xp);
assertTrue(alwaysTrue.execute(null).met());
}
@Test(expected = ConditionException.class)
public void testParser_Invalid() throws Exception {
Condition.Parser p = new AlwaysTrueCondition.Parser(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.field("foo", "bar");
builder.endObject();
XContentParser xp = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
xp.nextToken();
p.parse(xp);
fail("expected a condition exception trying to parse an invalid condition XContent, ["
+ AlwaysTrueCondition.TYPE + "] condition should not parse with a body");
}
@Test
public void testResultParser_Valid() throws Exception {
Condition.Parser p = new AlwaysTrueCondition.Parser(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.endObject();
XContentParser xp = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
xp.nextToken();
Condition.Result alwaysTrueResult = p.parseResult(xp);
assertTrue(alwaysTrueResult.met());
}
@Test(expected = ConditionException.class)
public void testResultParser_Invalid() throws Exception {
Condition.Parser p = new AlwaysTrueCondition.Parser(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.field("met", false );
builder.endObject();
XContentParser xp = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
xp.nextToken();
p.parseResult(xp);
fail("expected a condition exception trying to parse an invalid condition result XContent, ["
+ AlwaysTrueCondition.TYPE + "] condition result should not parse with a [met] field");
}
}

View File

@ -1,84 +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.condition.simple;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.ConditionException;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.test.ElasticsearchTestCase;
import org.junit.Test;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
/**
*/
public class AlwaysTrueConditionTests extends ElasticsearchTestCase {
@Test
public void testExecute() throws Exception {
Condition alwaysTrue = new AlwaysTrueCondition(logger);
assertTrue(alwaysTrue.execute(null).met());
}
@Test
public void testParser_Valid() throws Exception {
Condition.Parser p = new AlwaysTrueCondition.Parser(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.endObject();
XContentParser xp = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
xp.nextToken();
Condition alwaysTrue = p.parse(xp);
assertTrue(alwaysTrue.execute(null).met());
}
@Test(expected = ConditionException.class)
public void testParser_Invalid() throws Exception {
Condition.Parser p = new AlwaysTrueCondition.Parser(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.field("foo", "bar");
builder.endObject();
XContentParser xp = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
xp.nextToken();
p.parse(xp);
fail("expected a condition exception trying to parse an invalid condition XContent, ["
+ AlwaysTrueCondition.TYPE + "] condition should not parse with a body");
}
@Test
public void testResultParser_Valid() throws Exception {
Condition.Parser p = new AlwaysTrueCondition.Parser(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.endObject();
XContentParser xp = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
xp.nextToken();
Condition.Result alwaysTrueResult = p.parseResult(xp);
assertTrue(alwaysTrueResult.met());
}
@Test(expected = ConditionException.class)
public void testResultParser_Invalid() throws Exception {
Condition.Parser p = new AlwaysTrueCondition.Parser(ImmutableSettings.settingsBuilder().build());
XContentBuilder builder = jsonBuilder();
builder.startObject();
builder.field("met", false );
builder.endObject();
XContentParser xp = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
xp.nextToken();
p.parseResult(xp);
fail("expected a condition exception trying to parse an invalid condition result XContent, ["
+ AlwaysTrueCondition.TYPE + "] condition result should not parse with a [met] field");
}
}

View File

@ -11,12 +11,12 @@ import org.elasticsearch.common.joda.time.DateTimeZone;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.test.ElasticsearchTestCase;
import org.elasticsearch.watcher.actions.Action;
import org.elasticsearch.watcher.actions.ExecutableAction;
import org.elasticsearch.watcher.actions.ActionWrapper;
import org.elasticsearch.watcher.actions.ExecutableActions;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.simple.AlwaysFalseCondition;
import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition;
import org.elasticsearch.watcher.condition.ExecutableCondition;
import org.elasticsearch.watcher.condition.always.AlwaysCondition;
import org.elasticsearch.watcher.condition.never.NeverCondition;
import org.elasticsearch.watcher.history.HistoryStore;
import org.elasticsearch.watcher.input.Input;
import org.elasticsearch.watcher.support.clock.Clock;
@ -66,7 +66,7 @@ public class ExecutionServiceTests extends ElasticsearchTestCase {
@Test
public void testExecute() throws Exception {
Condition.Result conditionResult = AlwaysTrueCondition.RESULT;
Condition.Result conditionResult = AlwaysCondition.Result.INSTANCE;
Throttler.Result throttleResult = Throttler.Result.NO;
Transform.Result transformResult = mock(Transform.Result.class);
when(transformResult.payload()).thenReturn(payload);
@ -74,7 +74,7 @@ public class ExecutionServiceTests extends ElasticsearchTestCase {
when(actionResult.type()).thenReturn("_action_type");
ActionWrapper.Result watchActionResult = new ActionWrapper.Result("_id", null, actionResult);
Condition condition = mock(Condition.class);
ExecutableCondition condition = mock(ExecutableCondition.class);
when(condition.execute(any(WatchExecutionContext.class))).thenReturn(conditionResult);
Throttler throttler = mock(Throttler.class);
when(throttler.throttle(any(WatchExecutionContext.class))).thenReturn(throttleResult);
@ -111,7 +111,7 @@ public class ExecutionServiceTests extends ElasticsearchTestCase {
@Test
public void testExecute_throttled() throws Exception {
Condition.Result conditionResult = AlwaysTrueCondition.RESULT;
Condition.Result conditionResult = AlwaysCondition.Result.INSTANCE;
Throttler.Result throttleResult = mock(Throttler.Result.class);
when(throttleResult.throttle()).thenReturn(true);
@ -120,7 +120,7 @@ public class ExecutionServiceTests extends ElasticsearchTestCase {
ActionWrapper.Result actionResult = mock(ActionWrapper.Result.class);
when(actionResult.id()).thenReturn("_id");
Condition condition = mock(Condition.class);
ExecutableCondition condition = mock(ExecutableCondition.class);
when(condition.execute(any(WatchExecutionContext.class))).thenReturn(conditionResult);
Throttler throttler = mock(Throttler.class);
when(throttler.throttle(any(WatchExecutionContext.class))).thenReturn(throttleResult);
@ -158,7 +158,7 @@ public class ExecutionServiceTests extends ElasticsearchTestCase {
@Test
public void testExecute_conditionNotMet() throws Exception {
Condition.Result conditionResult = AlwaysFalseCondition.RESULT;
Condition.Result conditionResult = NeverCondition.Result.INSTANCE;
Throttler.Result throttleResult = mock(Throttler.Result.class);
when(throttleResult.throttle()).thenReturn(true);
@ -166,7 +166,7 @@ public class ExecutionServiceTests extends ElasticsearchTestCase {
ActionWrapper.Result actionResult = mock(ActionWrapper.Result.class);
when(actionResult.id()).thenReturn("_id");
Condition condition = mock(Condition.class);
ExecutableCondition condition = mock(ExecutableCondition.class);
when(condition.execute(any(WatchExecutionContext.class))).thenReturn(conditionResult);
Throttler throttler = mock(Throttler.class);
when(throttler.throttle(any(WatchExecutionContext.class))).thenReturn(throttleResult);

View File

@ -6,14 +6,12 @@
package org.elasticsearch.watcher.execution;
import com.carrotsearch.randomizedtesting.annotations.Repeat;
import org.elasticsearch.action.count.CountRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.watcher.actions.logging.LoggingAction;
import org.elasticsearch.watcher.client.WatchSourceBuilder;
import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition;
import org.elasticsearch.watcher.condition.always.AlwaysCondition;
import org.elasticsearch.watcher.history.HistoryStore;
import org.elasticsearch.watcher.history.WatchRecord;
import org.elasticsearch.watcher.support.template.Template;
import org.elasticsearch.watcher.test.AbstractWatcherIntegrationTests;
import org.elasticsearch.watcher.transport.actions.get.GetWatchRequest;
import org.elasticsearch.watcher.transport.actions.put.PutWatchRequest;
@ -21,11 +19,13 @@ import org.elasticsearch.watcher.transport.actions.put.PutWatchResponse;
import org.elasticsearch.watcher.watch.Watch;
import org.junit.Test;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
import static org.elasticsearch.watcher.actions.ActionBuilders.loggingAction;
import static org.elasticsearch.watcher.client.WatchSourceBuilders.watchBuilder;
import static org.elasticsearch.watcher.condition.ConditionBuilders.alwaysFalseCondition;
import static org.elasticsearch.watcher.condition.ConditionBuilders.alwaysTrueCondition;
import static org.elasticsearch.watcher.condition.ConditionBuilders.alwaysCondition;
import static org.elasticsearch.watcher.condition.ConditionBuilders.neverCondition;
import static org.elasticsearch.watcher.input.InputBuilders.simpleInput;
import static org.elasticsearch.watcher.trigger.TriggerBuilders.schedule;
import static org.elasticsearch.watcher.trigger.schedule.Schedules.cron;
@ -47,30 +47,27 @@ public class ManualExecutionTests extends AbstractWatcherIntegrationTests {
boolean conditionAlwaysTrue = randomBoolean();
String actionIdToSimulate = randomFrom("_all", "log", null);
LoggingAction.Builder loggingAction = LoggingAction.builder(new Template("foobar"));
WatchSourceBuilder testWatchBuilder = watchBuilder()
WatchSourceBuilder watchBuilder = watchBuilder()
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
.input(simpleInput("foo", "bar"))
.condition(conditionAlwaysTrue ? alwaysTrueCondition() : alwaysFalseCondition())
.addAction("log", loggingAction);
.condition(conditionAlwaysTrue ? alwaysCondition() : neverCondition())
.addAction("log", loggingAction("foobar"));
ManualExecutionContext.Builder ctxBuilder;
Watch parsedWatch = null;
if (recordExecution) {
PutWatchResponse putWatchResponse = watcherClient().putWatch(new PutWatchRequest("testwatch", testWatchBuilder)).actionGet();
PutWatchResponse putWatchResponse = watcherClient().putWatch(new PutWatchRequest("_id", watchBuilder)).actionGet();
assertThat(putWatchResponse.getVersion(), greaterThan(0L));
refresh();
assertThat(watcherClient().getWatch(new GetWatchRequest("testwatch")).actionGet().isFound(), equalTo(true));
ctxBuilder = ManualExecutionContext.builder(watchService().getWatch("testwatch")); //If we are persisting the state we need to use the exact watch that is in memory
assertThat(watcherClient().getWatch(new GetWatchRequest("_id")).actionGet().isFound(), equalTo(true));
ctxBuilder = ManualExecutionContext.builder(watchService().getWatch("_id")); //If we are persisting the state we need to use the exact watch that is in memory
} else {
parsedWatch = watchParser().parse("testwatch", false, testWatchBuilder.buildAsBytes(XContentType.JSON));
parsedWatch = watchParser().parse("_id", false, watchBuilder.buildAsBytes(XContentType.JSON));
ctxBuilder = ManualExecutionContext.builder(parsedWatch);
}
if (ignoreCondition) {
ctxBuilder.withCondition(AlwaysTrueCondition.RESULT);
ctxBuilder.withCondition(AlwaysCondition.Result.INSTANCE);
}
ctxBuilder.recordExecution(recordExecution);
@ -84,14 +81,15 @@ public class ManualExecutionTests extends AbstractWatcherIntegrationTests {
}
refresh();
long oldRecordCount = 0;
oldRecordCount = client().count(new CountRequest(HistoryStore.INDEX_PREFIX + "*")).actionGet().getCount();
long oldRecordCount = docCount(HistoryStore.INDEX_PREFIX + "*", HistoryStore.DOC_TYPE, matchAllQuery());
WatchRecord watchRecord = executionService().execute(ctxBuilder.build());
refresh();
long newRecordCount = client().count(new CountRequest(HistoryStore.INDEX_PREFIX + "*")).actionGet().getCount();
long newRecordCount = docCount(HistoryStore.INDEX_PREFIX + "*", HistoryStore.DOC_TYPE, matchAllQuery());
long expectedCount = oldRecordCount + (recordExecution ? 1 : 0);
assertThat("the expected count of history records should be [" + expectedCount + "]", newRecordCount, equalTo(expectedCount));
if (ignoreCondition) {
@ -109,10 +107,10 @@ public class ManualExecutionTests extends AbstractWatcherIntegrationTests {
assertThat("The action should have run simulated", watchRecord.execution().actionsResults().get("log").action(), instanceOf(LoggingAction.Result.Simulated.class));
}
Watch testWatch = watchService().getWatch("testwatch");
Watch testWatch = watchService().getWatch("_id");
if (recordExecution) {
refresh();
Watch persistedWatch = watchParser().parse("testwatch", true, watcherClient().getWatch(new GetWatchRequest("testwatch")).actionGet().getSource());
Watch persistedWatch = watchParser().parse("_id", true, watcherClient().getWatch(new GetWatchRequest("_id")).actionGet().getSource());
if (ignoreCondition || conditionAlwaysTrue) {
assertThat(testWatch.status().ackStatus().state(), equalTo(Watch.Status.AckStatus.State.ACKABLE));
assertThat(persistedWatch.status().ackStatus().state(), equalTo(Watch.Status.AckStatus.State.ACKABLE));

View File

@ -9,14 +9,13 @@ import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.common.joda.time.DateTime;
import org.elasticsearch.common.joda.time.DateTimeZone;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition;
import org.elasticsearch.watcher.condition.ExecutableCondition;
import org.elasticsearch.watcher.condition.always.ExecutableAlwaysCondition;
import org.elasticsearch.watcher.execution.Wid;
import org.elasticsearch.watcher.support.clock.SystemClock;
import org.elasticsearch.watcher.test.AbstractWatcherIntegrationTests;
import org.elasticsearch.watcher.trigger.schedule.ScheduleTriggerEvent;
import org.elasticsearch.watcher.watch.Watch;
import org.junit.Ignore;
import org.junit.Test;
import java.util.Collection;
@ -30,7 +29,7 @@ public class HistoryStoreLifeCycleTest extends AbstractWatcherIntegrationTests {
@Test
public void testPutLoadUpdate() throws Exception {
Condition condition = new AlwaysTrueCondition(logger);
ExecutableCondition condition = new ExecutableAlwaysCondition(logger);
HistoryStore historyStore = getInstanceFromMaster(HistoryStore.class);
Watch watch = new Watch("_name", SystemClock.INSTANCE, licenseService(), null, null, condition, null, null, null, null, null);

View File

@ -31,7 +31,7 @@ import org.elasticsearch.search.internal.InternalSearchHit;
import org.elasticsearch.search.internal.InternalSearchHits;
import org.elasticsearch.search.internal.InternalSearchResponse;
import org.elasticsearch.test.ElasticsearchTestCase;
import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition;
import org.elasticsearch.watcher.condition.always.ExecutableAlwaysCondition;
import org.elasticsearch.watcher.execution.Wid;
import org.elasticsearch.watcher.support.TemplateUtils;
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
@ -73,7 +73,7 @@ public class HistoryStoreTests extends ElasticsearchTestCase {
public void testPut() throws Exception {
Watch watch = mock(Watch.class);
when(watch.name()).thenReturn("_name");
when(watch.condition()).thenReturn(new AlwaysTrueCondition(logger));
when(watch.condition()).thenReturn(new ExecutableAlwaysCondition(logger));
when(watch.input()).thenReturn(null);
when(watch.metadata()).thenReturn(null);
ScheduleTriggerEvent event = new ScheduleTriggerEvent(new DateTime(0, DateTimeZone.UTC), new DateTime(0, DateTimeZone.UTC));
@ -93,7 +93,7 @@ public class HistoryStoreTests extends ElasticsearchTestCase {
public void testUpdate() throws Exception {
Watch watch = mock(Watch.class);
when(watch.name()).thenReturn("_name");
when(watch.condition()).thenReturn(new AlwaysTrueCondition(logger));
when(watch.condition()).thenReturn(new ExecutableAlwaysCondition(logger));
when(watch.input()).thenReturn(null);
when(watch.metadata()).thenReturn(null);
ScheduleTriggerEvent event = new ScheduleTriggerEvent(new DateTime(0, DateTimeZone.UTC), new DateTime(0, DateTimeZone.UTC));
@ -114,7 +114,7 @@ public class HistoryStoreTests extends ElasticsearchTestCase {
public void testPut_stopped() {
Watch watch = mock(Watch.class);
when(watch.name()).thenReturn("_name");
when(watch.condition()).thenReturn(new AlwaysTrueCondition(logger));
when(watch.condition()).thenReturn(new ExecutableAlwaysCondition(logger));
when(watch.input()).thenReturn(null);
when(watch.metadata()).thenReturn(null);
ScheduleTriggerEvent event = new ScheduleTriggerEvent(new DateTime(0, DateTimeZone.UTC), new DateTime(0, DateTimeZone.UTC));
@ -134,7 +134,7 @@ public class HistoryStoreTests extends ElasticsearchTestCase {
public void testUpdate_stopped() throws Exception {
Watch watch = mock(Watch.class);
when(watch.name()).thenReturn("_name");
when(watch.condition()).thenReturn(new AlwaysTrueCondition(logger));
when(watch.condition()).thenReturn(new ExecutableAlwaysCondition(logger));
when(watch.input()).thenReturn(null);
when(watch.metadata()).thenReturn(null);
ScheduleTriggerEvent event = new ScheduleTriggerEvent(new DateTime(0, DateTimeZone.UTC), new DateTime(0, DateTimeZone.UTC));

View File

@ -13,8 +13,7 @@ import org.elasticsearch.watcher.actions.ActionWrapper;
import org.elasticsearch.watcher.actions.email.EmailAction;
import org.elasticsearch.watcher.actions.webhook.WebhookAction;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.simple.AlwaysFalseCondition;
import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition;
import org.elasticsearch.watcher.condition.always.AlwaysCondition;
import org.elasticsearch.watcher.execution.TriggeredExecutionContext;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
import org.elasticsearch.watcher.execution.Wid;
@ -68,7 +67,7 @@ public class WatchRecordTests extends AbstractWatcherIntegrationTests {
.build();
ctx.onActionResult(new ActionWrapper.Result("_webhook", new WebhookAction.Result.Executed(request, new HttpResponse(300))));
Input.Result inputResult = new SimpleInput.Result(new Payload.Simple());
Condition.Result conditionResult = AlwaysTrueCondition.RESULT;
Condition.Result conditionResult = AlwaysCondition.Result.INSTANCE;
ctx.onThrottleResult(Throttler.NO_THROTTLE.throttle(ctx));
ctx.onInputResult(inputResult);
ctx.onConditionResult(conditionResult);
@ -97,7 +96,7 @@ public class WatchRecordTests extends AbstractWatcherIntegrationTests {
.build();
ctx.onActionResult(new ActionWrapper.Result("_webhook", new WebhookAction.Result.Executed(request, new HttpResponse(300))));
Input.Result inputResult = new SimpleInput.Result(new Payload.Simple());
Condition.Result conditionResult = AlwaysFalseCondition.RESULT;
Condition.Result conditionResult = AlwaysCondition.Result.INSTANCE;
ctx.onThrottleResult(Throttler.NO_THROTTLE.throttle(ctx));
ctx.onInputResult(inputResult);
ctx.onConditionResult(conditionResult);

View File

@ -18,7 +18,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.test.ElasticsearchTestCase;
import org.elasticsearch.watcher.actions.ActionWrapper;
import org.elasticsearch.watcher.actions.ExecutableActions;
import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition;
import org.elasticsearch.watcher.condition.always.ExecutableAlwaysCondition;
import org.elasticsearch.watcher.execution.TriggeredExecutionContext;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
import org.elasticsearch.watcher.input.Input;
@ -85,7 +85,7 @@ public class HttpInputTests extends ElasticsearchTestCase {
mock(LicenseService.class),
new ScheduleTrigger(new IntervalSchedule(new IntervalSchedule.Interval(1, IntervalSchedule.Interval.Unit.MINUTES))),
new SimpleInput(logger, new Payload.Simple()),
new AlwaysTrueCondition(logger),
new ExecutableAlwaysCondition(logger),
null,
new ExecutableActions(new ArrayList<ActionWrapper>()),
null,

View File

@ -21,7 +21,7 @@ import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.watcher.actions.ActionWrapper;
import org.elasticsearch.watcher.actions.ExecutableActions;
import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition;
import org.elasticsearch.watcher.condition.always.ExecutableAlwaysCondition;
import org.elasticsearch.watcher.input.Input;
import org.elasticsearch.watcher.input.InputException;
import org.elasticsearch.watcher.input.simple.SimpleInput;
@ -76,7 +76,7 @@ public class SearchInputTests extends ElasticsearchIntegrationTest {
mock(LicenseService.class),
new ScheduleTrigger(new IntervalSchedule(new IntervalSchedule.Interval(1, IntervalSchedule.Interval.Unit.MINUTES))),
new SimpleInput(logger, new Payload.Simple()),
new AlwaysTrueCondition(logger),
new ExecutableAlwaysCondition(logger),
null,
new ExecutableActions(new ArrayList<ActionWrapper>()),
null,
@ -114,7 +114,7 @@ public class SearchInputTests extends ElasticsearchIntegrationTest {
mock(LicenseService.class),
new ScheduleTrigger(new IntervalSchedule(new IntervalSchedule.Interval(1, IntervalSchedule.Interval.Unit.MINUTES))),
new SimpleInput(logger, new Payload.Simple()),
new AlwaysTrueCondition(logger),
new ExecutableAlwaysCondition(logger),
null,
new ExecutableActions(new ArrayList<ActionWrapper>()),
null,

View File

@ -36,7 +36,7 @@ import static org.elasticsearch.index.query.FilterBuilders.termFilter;
import static org.elasticsearch.index.query.QueryBuilders.*;
import static org.elasticsearch.watcher.actions.ActionBuilders.indexAction;
import static org.elasticsearch.watcher.client.WatchSourceBuilders.watchBuilder;
import static org.elasticsearch.watcher.condition.ConditionBuilders.alwaysTrueCondition;
import static org.elasticsearch.watcher.condition.ConditionBuilders.alwaysCondition;
import static org.elasticsearch.watcher.input.InputBuilders.simpleInput;
import static org.elasticsearch.watcher.trigger.TriggerBuilders.schedule;
import static org.elasticsearch.watcher.trigger.schedule.Schedules.interval;
@ -78,7 +78,7 @@ public class LicenseIntegrationTests extends AbstractWatcherIntegrationTests {
PutWatchResponse putWatchResponse = watcherClient().preparePutWatch(watchName).setSource(watchBuilder()
.trigger(schedule(interval("1s")))
.input(simpleInput())
.condition(alwaysTrueCondition())
.condition(alwaysCondition())
.addAction("_index", indexAction("idx", "type")))
.execute().actionGet();
@ -111,7 +111,7 @@ public class LicenseIntegrationTests extends AbstractWatcherIntegrationTests {
putWatchResponse = watcherClient().preparePutWatch(watchName).setSource(watchBuilder()
.trigger(schedule(interval("10s")))
.input(simpleInput())
.condition(alwaysTrueCondition())
.condition(alwaysCondition())
.addAction("_index", indexAction("idx", "type")))
.execute().actionGet();
@ -171,7 +171,7 @@ public class LicenseIntegrationTests extends AbstractWatcherIntegrationTests {
watcherClient().preparePutWatch(watchName).setSource(watchBuilder()
.trigger(schedule(interval("1s")))
.input(simpleInput())
.condition(alwaysTrueCondition())
.condition(alwaysCondition())
.addAction("_index", indexAction("idx", "type")))
.execute().actionGet();
fail("put watch API should NOT work when license is disabled");
@ -227,7 +227,7 @@ public class LicenseIntegrationTests extends AbstractWatcherIntegrationTests {
putWatchResponse = watcherClient().preparePutWatch(watchName).setSource(watchBuilder()
.trigger(schedule(interval("1s")))
.input(simpleInput())
.condition(alwaysTrueCondition())
.condition(alwaysCondition())
.addAction("_index", indexAction("idx", "type")))
.execute().actionGet();

View File

@ -26,6 +26,7 @@ import org.elasticsearch.watcher.actions.email.service.EmailTemplate;
import org.elasticsearch.watcher.actions.email.service.Profile;
import org.elasticsearch.watcher.actions.webhook.ExecutableWebhookAction;
import org.elasticsearch.watcher.actions.webhook.WebhookAction;
import org.elasticsearch.watcher.condition.script.ExecutableScriptCondition;
import org.elasticsearch.watcher.condition.script.ScriptCondition;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
import org.elasticsearch.watcher.input.search.SearchInput;
@ -96,8 +97,8 @@ public final class WatcherTestUtils {
return new Payload.Simple(key, value);
}
public static WatchExecutionContext mockExecutionContext(String watchName, Payload payload) {
return mockExecutionContext(watchName, DateTime.now(UTC), payload);
public static WatchExecutionContext mockExecutionContext(String watchId, Payload payload) {
return mockExecutionContext(watchId, DateTime.now(UTC), payload);
}
public static WatchExecutionContext mockExecutionContext(String watchName, DateTime time, Payload payload) {
@ -174,7 +175,7 @@ public final class WatcherTestUtils {
licenseService,
new ScheduleTrigger(new CronSchedule("0/5 * * * * ? *")),
new SimpleInput(logger, new Payload.Simple(inputData)),
new ScriptCondition(logger, scriptService, new Script("return true")),
new ExecutableScriptCondition(new ScriptCondition(new Script("return true")), logger, scriptService),
new SearchTransform(logger, scriptService, client, transformRequest),
new ExecutableActions(actions),
metadata,

View File

@ -16,6 +16,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.test.junit.annotations.TestLogging;
import org.elasticsearch.watcher.actions.ActionWrapper;
import org.elasticsearch.watcher.actions.ExecutableActions;
import org.elasticsearch.watcher.condition.script.ExecutableScriptCondition;
import org.elasticsearch.watcher.condition.script.ScriptCondition;
import org.elasticsearch.watcher.execution.Wid;
import org.elasticsearch.watcher.history.HistoryStore;
@ -35,7 +36,6 @@ import org.elasticsearch.watcher.trigger.schedule.ScheduleTriggerEvent;
import org.elasticsearch.watcher.watch.Watch;
import org.elasticsearch.watcher.watch.WatchService;
import org.elasticsearch.watcher.watch.WatchStore;
import org.junit.Ignore;
import org.junit.Test;
import java.util.ArrayList;
@ -89,7 +89,7 @@ public class BootStrapTests extends AbstractWatcherIntegrationTests {
licenseService(),
new ScheduleTrigger(new CronSchedule("0/5 * * * * ? 2035")), //Set this into the future so we don't get any extra runs
new SearchInput(logger, scriptService(), ClientProxy.of(client()), searchRequest, null),
new ScriptCondition(logger, scriptService(), new Script("return true")),
new ExecutableScriptCondition(new ScriptCondition(new Script("return true")), logger, scriptService()),
new SearchTransform(logger, scriptService(), ClientProxy.of(client()), searchRequest),
new ExecutableActions(new ArrayList<ActionWrapper>()),
null, // metadata
@ -152,7 +152,7 @@ public class BootStrapTests extends AbstractWatcherIntegrationTests {
new ScheduleTrigger(new CronSchedule("0/5 * * * * ? 2035")), //Set a cron schedule far into the future so this watch is never scheduled
new SearchInput(logger, scriptService(), ClientProxy.of(client()),
searchRequest, null),
new ScriptCondition(logger, scriptService(), new Script("return true")),
new ExecutableScriptCondition(new ScriptCondition(new Script("return true")), logger, scriptService()),
new SearchTransform(logger, scriptService(), ClientProxy.of(client()), searchRequest),
new ExecutableActions(new ArrayList<ActionWrapper>()),
null, // metatdata

View File

@ -19,7 +19,7 @@ import java.util.Map;
import static org.elasticsearch.watcher.actions.ActionBuilders.loggingAction;
import static org.elasticsearch.watcher.client.WatchSourceBuilders.watchBuilder;
import static org.elasticsearch.watcher.condition.ConditionBuilders.alwaysTrueCondition;
import static org.elasticsearch.watcher.condition.ConditionBuilders.alwaysCondition;
import static org.elasticsearch.watcher.input.InputBuilders.simpleInput;
import static org.elasticsearch.watcher.trigger.TriggerBuilders.schedule;
import static org.elasticsearch.watcher.trigger.schedule.Schedules.interval;
@ -41,7 +41,7 @@ public class WatchCrudTests extends AbstractWatcherIntegrationTests {
source.input(simpleInput());
}
if (randomBoolean()) {
source.condition(alwaysTrueCondition());
source.condition(alwaysCondition());
}
if (randomBoolean()) {
source.addAction("_action1", loggingAction("{{ctx.watch_id}}"));
@ -59,7 +59,7 @@ public class WatchCrudTests extends AbstractWatcherIntegrationTests {
ensureWatcherStarted();
watcherClient().preparePutWatch("_name").setSource(watchBuilder()
.input(simpleInput())
.condition(alwaysTrueCondition())
.condition(alwaysCondition())
.addAction("_action1", loggingAction("{{ctx.watch_id}}")))
.get();
}
@ -70,7 +70,7 @@ public class WatchCrudTests extends AbstractWatcherIntegrationTests {
PutWatchResponse putResponse = watcherClient().preparePutWatch("_name").setSource(watchBuilder()
.trigger(schedule(interval("5m")))
.input(simpleInput())
.condition(alwaysTrueCondition())
.condition(alwaysCondition())
.addAction("_action1", loggingAction("{{ctx.watch_id}}")))
.get();
@ -111,7 +111,7 @@ public class WatchCrudTests extends AbstractWatcherIntegrationTests {
PutWatchResponse putResponse = watcherClient().preparePutWatch("_name").setSource(watchBuilder()
.trigger(schedule(interval("5m")))
.input(simpleInput())
.condition(alwaysTrueCondition())
.condition(alwaysCondition())
.addAction("_action1", loggingAction("{{ctx.watch_id}}")))
.get();

View File

@ -34,10 +34,15 @@ import org.elasticsearch.watcher.actions.index.IndexActionFactory;
import org.elasticsearch.watcher.actions.webhook.ExecutableWebhookAction;
import org.elasticsearch.watcher.actions.webhook.WebhookAction;
import org.elasticsearch.watcher.actions.webhook.WebhookActionFactory;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.ConditionFactory;
import org.elasticsearch.watcher.condition.ConditionRegistry;
import org.elasticsearch.watcher.condition.ExecutableCondition;
import org.elasticsearch.watcher.condition.always.AlwaysCondition;
import org.elasticsearch.watcher.condition.always.AlwaysConditionFactory;
import org.elasticsearch.watcher.condition.always.ExecutableAlwaysCondition;
import org.elasticsearch.watcher.condition.script.ExecutableScriptCondition;
import org.elasticsearch.watcher.condition.script.ScriptCondition;
import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition;
import org.elasticsearch.watcher.condition.script.ScriptConditionFactory;
import org.elasticsearch.watcher.input.Input;
import org.elasticsearch.watcher.input.InputRegistry;
import org.elasticsearch.watcher.input.search.SearchInput;
@ -111,7 +116,7 @@ public class WatchTests extends ElasticsearchTestCase {
Input input = randomInput();
InputRegistry inputRegistry = registry(input);
Condition condition = randomCondition();
ExecutableCondition condition = randomCondition();
ConditionRegistry conditionRegistry = registry(condition);
Transform transform = randomTransform();
@ -218,24 +223,24 @@ public class WatchTests extends ElasticsearchTestCase {
}
}
private Condition randomCondition() {
String type = randomFrom(ScriptCondition.TYPE, AlwaysTrueCondition.TYPE);
private ExecutableCondition randomCondition() {
String type = randomFrom(ScriptCondition.TYPE, AlwaysCondition.TYPE);
switch (type) {
case ScriptCondition.TYPE:
return new ScriptCondition(logger, scriptService, new Script("_script"));
return new ExecutableScriptCondition(new ScriptCondition(new Script("_script")), logger, scriptService);
default:
return new AlwaysTrueCondition(logger);
return new ExecutableAlwaysCondition(logger);
}
}
private ConditionRegistry registry(Condition condition) {
ImmutableMap.Builder<String, Condition.Parser> parsers = ImmutableMap.builder();
private ConditionRegistry registry(ExecutableCondition condition) {
ImmutableMap.Builder<String, ConditionFactory> parsers = ImmutableMap.builder();
switch (condition.type()) {
case ScriptCondition.TYPE:
parsers.put(ScriptCondition.TYPE, new ScriptCondition.Parser(settings, scriptService));
parsers.put(ScriptCondition.TYPE, new ScriptConditionFactory(settings, scriptService));
return new ConditionRegistry(parsers.build());
default:
parsers.put(AlwaysTrueCondition.TYPE, new AlwaysTrueCondition.Parser(settings));
parsers.put(AlwaysCondition.TYPE, new AlwaysConditionFactory(settings));
return new ConditionRegistry(parsers.build());
}
}