diff --git a/src/main/java/org/elasticsearch/watcher/client/WatchSourceBuilder.java b/src/main/java/org/elasticsearch/watcher/client/WatchSourceBuilder.java index 846f3ffe956..1b5841d4b4a 100644 --- a/src/main/java/org/elasticsearch/watcher/client/WatchSourceBuilder.java +++ b/src/main/java/org/elasticsearch/watcher/client/WatchSourceBuilder.java @@ -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 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; } diff --git a/src/main/java/org/elasticsearch/watcher/condition/Condition.java b/src/main/java/org/elasticsearch/watcher/condition/Condition.java index 9c999b804d5..7a975c1cc5e 100644 --- a/src/main/java/org/elasticsearch/watcher/condition/Condition.java +++ b/src/main/java/org/elasticsearch/watcher/condition/Condition.java @@ -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 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> { - - /** - * @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 implements ToXConten } - public static interface SourceBuilder extends ToXContent { + interface Builder { - public String type(); + C build(); + } + interface Field { + ParseField MET = new ParseField("met"); } } diff --git a/src/main/java/org/elasticsearch/watcher/condition/ConditionBuilders.java b/src/main/java/org/elasticsearch/watcher/condition/ConditionBuilders.java index 9d08d3cb972..fdb045d1924 100644 --- a/src/main/java/org/elasticsearch/watcher/condition/ConditionBuilders.java +++ b/src/main/java/org/elasticsearch/watcher/condition/ConditionBuilders.java @@ -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); - } - } diff --git a/src/main/java/org/elasticsearch/watcher/condition/ConditionException.java b/src/main/java/org/elasticsearch/watcher/condition/ConditionException.java index 83ddbf843a9..dbd916fbd16 100644 --- a/src/main/java/org/elasticsearch/watcher/condition/ConditionException.java +++ b/src/main/java/org/elasticsearch/watcher/condition/ConditionException.java @@ -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); } } diff --git a/src/main/java/org/elasticsearch/watcher/condition/ConditionFactory.java b/src/main/java/org/elasticsearch/watcher/condition/ConditionFactory.java new file mode 100644 index 00000000000..40d2e6e79dd --- /dev/null +++ b/src/main/java/org/elasticsearch/watcher/condition/ConditionFactory.java @@ -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> { + + 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); +} diff --git a/src/main/java/org/elasticsearch/watcher/condition/ConditionModule.java b/src/main/java/org/elasticsearch/watcher/condition/ConditionModule.java index 3d159ad9a59..25c88544966 100644 --- a/src/main/java/org/elasticsearch/watcher/condition/ConditionModule.java +++ b/src/main/java/org/elasticsearch/watcher/condition/ConditionModule.java @@ -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> parsers = new HashMap<>(); + private final Map> factories = new HashMap<>(); - public void registerCondition(String type, Class parserType) { - parsers.put(type, parserType); + public void registerCondition(String type, Class factoryType) { + factories.put(type, factoryType); } @Override protected void configure() { - MapBinder 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 factoriesBinder = MapBinder.newMapBinder(binder(), String.class, ConditionFactory.class); - for (Map.Entry> 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> 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(); diff --git a/src/main/java/org/elasticsearch/watcher/condition/ConditionRegistry.java b/src/main/java/org/elasticsearch/watcher/condition/ConditionRegistry.java index 45dba570096..feeab65dfdb 100644 --- a/src/main/java/org/elasticsearch/watcher/condition/ConditionRegistry.java +++ b/src/main/java/org/elasticsearch/watcher/condition/ConditionRegistry.java @@ -18,74 +18,99 @@ import java.util.Set; */ public class ConditionRegistry { - private final ImmutableMap parsers; + private final ImmutableMap factories; @Inject - public ConditionRegistry(Map parsers) { - this.parsers = ImmutableMap.copyOf(parsers); + public ConditionRegistry(Map factories) { + this.factories = ImmutableMap.copyOf(factories); } public Set 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: + *
+     *     {
+     *         "condition_type" : {
+     *             ...              //condition body
+     *         }
+     *     }
+     * 
*/ - 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: + *
+     *     {
+     *         "condition_type" : {
+     *             ...              //condition body
+     *         }
+     *     }
+     * 
+ */ + 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: + *
+     *     {
+     *         "condition_type" : {
+     *             ...              // result body
+     *         }
+     *     }
+     * 
*/ - 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; } } diff --git a/src/main/java/org/elasticsearch/watcher/condition/ExecutableCondition.java b/src/main/java/org/elasticsearch/watcher/condition/ExecutableCondition.java new file mode 100644 index 00000000000..7cf5555b2fb --- /dev/null +++ b/src/main/java/org/elasticsearch/watcher/condition/ExecutableCondition.java @@ -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 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(); + } +} diff --git a/src/main/java/org/elasticsearch/watcher/condition/always/AlwaysCondition.java b/src/main/java/org/elasticsearch/watcher/condition/always/AlwaysCondition.java new file mode 100644 index 00000000000..0a8e4f48256 --- /dev/null +++ b/src/main/java/org/elasticsearch/watcher/condition/always/AlwaysCondition.java @@ -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 { + + public static final Builder INSTANCE = new Builder(); + + public AlwaysCondition build() { + return AlwaysCondition.INSTANCE; + } + } +} diff --git a/src/main/java/org/elasticsearch/watcher/condition/always/AlwaysConditionException.java b/src/main/java/org/elasticsearch/watcher/condition/always/AlwaysConditionException.java new file mode 100644 index 00000000000..151f8bfabc2 --- /dev/null +++ b/src/main/java/org/elasticsearch/watcher/condition/always/AlwaysConditionException.java @@ -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); + } +} diff --git a/src/main/java/org/elasticsearch/watcher/condition/always/AlwaysConditionFactory.java b/src/main/java/org/elasticsearch/watcher/condition/always/AlwaysConditionFactory.java new file mode 100644 index 00000000000..d9a91c37863 --- /dev/null +++ b/src/main/java/org/elasticsearch/watcher/condition/always/AlwaysConditionFactory.java @@ -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 { + + 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; + } +} diff --git a/src/main/java/org/elasticsearch/watcher/condition/always/ExecutableAlwaysCondition.java b/src/main/java/org/elasticsearch/watcher/condition/always/ExecutableAlwaysCondition.java new file mode 100644 index 00000000000..a80874a4ad2 --- /dev/null +++ b/src/main/java/org/elasticsearch/watcher/condition/always/ExecutableAlwaysCondition.java @@ -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 { + + 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; + } + +} diff --git a/src/main/java/org/elasticsearch/watcher/condition/never/ExecutableNeverCondition.java b/src/main/java/org/elasticsearch/watcher/condition/never/ExecutableNeverCondition.java new file mode 100644 index 00000000000..cfd40a1fdfe --- /dev/null +++ b/src/main/java/org/elasticsearch/watcher/condition/never/ExecutableNeverCondition.java @@ -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 { + + 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; + } + +} diff --git a/src/main/java/org/elasticsearch/watcher/condition/never/NeverCondition.java b/src/main/java/org/elasticsearch/watcher/condition/never/NeverCondition.java new file mode 100644 index 00000000000..29824a7b6bc --- /dev/null +++ b/src/main/java/org/elasticsearch/watcher/condition/never/NeverCondition.java @@ -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 { + + public static final Builder INSTANCE = new Builder(); + + public NeverCondition build() { + return NeverCondition.INSTANCE; + } + } +} diff --git a/src/main/java/org/elasticsearch/watcher/condition/never/NeverConditionException.java b/src/main/java/org/elasticsearch/watcher/condition/never/NeverConditionException.java new file mode 100644 index 00000000000..f13d5a7972e --- /dev/null +++ b/src/main/java/org/elasticsearch/watcher/condition/never/NeverConditionException.java @@ -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); + } +} diff --git a/src/main/java/org/elasticsearch/watcher/condition/never/NeverConditionFactory.java b/src/main/java/org/elasticsearch/watcher/condition/never/NeverConditionFactory.java new file mode 100644 index 00000000000..84dc09a5241 --- /dev/null +++ b/src/main/java/org/elasticsearch/watcher/condition/never/NeverConditionFactory.java @@ -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 { + + 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; + } +} diff --git a/src/main/java/org/elasticsearch/watcher/condition/script/ExecutableScriptCondition.java b/src/main/java/org/elasticsearch/watcher/condition/script/ExecutableScriptCondition.java new file mode 100644 index 00000000000..e0fcabacc32 --- /dev/null +++ b/src/main/java/org/elasticsearch/watcher/condition/script/ExecutableScriptCondition.java @@ -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 { + + 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); + } +} diff --git a/src/main/java/org/elasticsearch/watcher/condition/script/ScriptCondition.java b/src/main/java/org/elasticsearch/watcher/condition/script/ScriptCondition.java index 8d57a47647b..30fc3f08fcd 100644 --- a/src/main/java/org/elasticsearch/watcher/condition/script/ScriptCondition.java +++ b/src/main/java/org/elasticsearch/watcher/condition/script/ScriptCondition.java @@ -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 { +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 model = ImmutableMap.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 { 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 { return script.hashCode(); } - public static class Parser extends AbstractComponent implements Condition.Parser { - - 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 { @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 { - private String script; - private String lang = ScriptService.DEFAULT_LANG; - private ScriptService.ScriptType type = ScriptService.ScriptType.INLINE; - private Map params = Collections.emptyMap(); + private final String script; + private ScriptService.ScriptType type = Script.DEFAULT_TYPE; + private String lang = Script.DEFAULT_LANG; + private ImmutableMap.Builder 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 params) { - this.params = params; + public Builder setLang(String lang) { + this.lang = lang; + return this; + } + + public Builder addVars(Map 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())); } } } diff --git a/src/main/java/org/elasticsearch/watcher/condition/script/ScriptConditionException.java b/src/main/java/org/elasticsearch/watcher/condition/script/ScriptConditionException.java new file mode 100644 index 00000000000..84d48322398 --- /dev/null +++ b/src/main/java/org/elasticsearch/watcher/condition/script/ScriptConditionException.java @@ -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); + } +} diff --git a/src/main/java/org/elasticsearch/watcher/condition/script/ScriptConditionFactory.java b/src/main/java/org/elasticsearch/watcher/condition/script/ScriptConditionFactory.java new file mode 100644 index 00000000000..152c8a3eb63 --- /dev/null +++ b/src/main/java/org/elasticsearch/watcher/condition/script/ScriptConditionFactory.java @@ -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 { + + 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); + } +} diff --git a/src/main/java/org/elasticsearch/watcher/condition/simple/AlwaysFalseCondition.java b/src/main/java/org/elasticsearch/watcher/condition/simple/AlwaysFalseCondition.java deleted file mode 100644 index c1a6d5b173c..00000000000 --- a/src/main/java/org/elasticsearch/watcher/condition/simple/AlwaysFalseCondition.java +++ /dev/null @@ -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 { - - 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 { - - @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(); - } - } - -} diff --git a/src/main/java/org/elasticsearch/watcher/condition/simple/AlwaysTrueCondition.java b/src/main/java/org/elasticsearch/watcher/condition/simple/AlwaysTrueCondition.java deleted file mode 100644 index 229e135fa71..00000000000 --- a/src/main/java/org/elasticsearch/watcher/condition/simple/AlwaysTrueCondition.java +++ /dev/null @@ -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 { - - 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 { - - @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(); - } - } -} diff --git a/src/main/java/org/elasticsearch/watcher/execution/WatchExecutionContext.java b/src/main/java/org/elasticsearch/watcher/execution/WatchExecutionContext.java index e49fdc42bd3..dd844af3d6a 100644 --- a/src/main/java/org/elasticsearch/watcher/execution/WatchExecutionContext.java +++ b/src/main/java/org/elasticsearch/watcher/execution/WatchExecutionContext.java @@ -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; diff --git a/src/main/java/org/elasticsearch/watcher/history/WatchRecord.java b/src/main/java/org/elasticsearch/watcher/history/WatchRecord.java index 6c9772c1b5b..d5eb4f1478f 100644 --- a/src/main/java/org/elasticsearch/watcher/history/WatchRecord.java +++ b/src/main/java/org/elasticsearch/watcher/history/WatchRecord.java @@ -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)) { diff --git a/src/main/java/org/elasticsearch/watcher/support/Script.java b/src/main/java/org/elasticsearch/watcher/support/Script.java index 1e0b7982aac..580f3e21b82 100644 --- a/src/main/java/org/elasticsearch/watcher/support/Script.java +++ b/src/main/java/org/elasticsearch/watcher/support/Script.java @@ -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 params; public Script(String script) { - this(script, ScriptService.ScriptType.INLINE, ScriptService.DEFAULT_LANG, Collections.emptyMap()); + this(script, DEFAULT_TYPE, DEFAULT_LANG, Collections.emptyMap()); } public Script(String script, ScriptService.ScriptType type, String lang) { diff --git a/src/main/java/org/elasticsearch/watcher/support/init/proxy/ScriptServiceProxy.java b/src/main/java/org/elasticsearch/watcher/support/init/proxy/ScriptServiceProxy.java index 3fcc16f9d73..18d38207f1a 100644 --- a/src/main/java/org/elasticsearch/watcher/support/init/proxy/ScriptServiceProxy.java +++ b/src/main/java/org/elasticsearch/watcher/support/init/proxy/ScriptServiceProxy.java @@ -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 vars) { + if (script.params() != null && !script.params().isEmpty()) { + vars = ImmutableMap.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 vars) { return service.executable(lang, script, scriptType, vars); } diff --git a/src/main/java/org/elasticsearch/watcher/transport/actions/execute/TransportExecuteWatchAction.java b/src/main/java/org/elasticsearch/watcher/transport/actions/execute/TransportExecuteWatchAction.java index 83065a5b4bf..f51f2fb18ee 100644 --- a/src/main/java/org/elasticsearch/watcher/transport/actions/execute/TransportExecuteWatchAction.java +++ b/src/main/java/org/elasticsearch/watcher/transport/actions/execute/TransportExecuteWatchAction.java @@ -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 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 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)) { diff --git a/src/main/java/org/elasticsearch/watcher/watch/WatchExecution.java b/src/main/java/org/elasticsearch/watcher/watch/WatchExecution.java index 7ee3c235efb..d2a33d4c9fc 100644 --- a/src/main/java/org/elasticsearch/watcher/watch/WatchExecution.java +++ b/src/main/java/org/elasticsearch/watcher/watch/WatchExecution.java @@ -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)) { diff --git a/src/test/java/org/elasticsearch/watcher/condition/always/AlwaysConditionTests.java b/src/test/java/org/elasticsearch/watcher/condition/always/AlwaysConditionTests.java new file mode 100644 index 00000000000..e3e0a6ff3de --- /dev/null +++ b/src/test/java/org/elasticsearch/watcher/condition/always/AlwaysConditionTests.java @@ -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"); + } + +} diff --git a/src/test/java/org/elasticsearch/watcher/condition/never/NeverConditionTests.java b/src/test/java/org/elasticsearch/watcher/condition/never/NeverConditionTests.java new file mode 100644 index 00000000000..0ed98764f26 --- /dev/null +++ b/src/test/java/org/elasticsearch/watcher/condition/never/NeverConditionTests.java @@ -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"); + } +} diff --git a/src/test/java/org/elasticsearch/watcher/condition/script/ScriptConditionSearchTests.java b/src/test/java/org/elasticsearch/watcher/condition/script/ScriptConditionSearchTests.java index 09fa6f9609e..3ff041e3493 100644 --- a/src/test/java/org/elasticsearch/watcher/condition/script/ScriptConditionSearchTests.java +++ b/src/test/java/org/elasticsearch/watcher/condition/script/ScriptConditionSearchTests.java @@ -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)); diff --git a/src/test/java/org/elasticsearch/watcher/condition/script/ScriptConditionTests.java b/src/test/java/org/elasticsearch/watcher/condition/script/ScriptConditionTests.java index 1547a5e0e28..492a755af36 100644 --- a/src/test/java/org/elasticsearch/watcher/condition/script/ScriptConditionTests.java +++ b/src/test/java/org/elasticsearch/watcher/condition/script/ScriptConditionTests.java @@ -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.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"); } diff --git a/src/test/java/org/elasticsearch/watcher/condition/simple/AlwaysFalseConditionTests.java b/src/test/java/org/elasticsearch/watcher/condition/simple/AlwaysFalseConditionTests.java deleted file mode 100644 index d074ca8ba07..00000000000 --- a/src/test/java/org/elasticsearch/watcher/condition/simple/AlwaysFalseConditionTests.java +++ /dev/null @@ -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"); - } -} diff --git a/src/test/java/org/elasticsearch/watcher/condition/simple/AlwaysTrueConditionTests.java b/src/test/java/org/elasticsearch/watcher/condition/simple/AlwaysTrueConditionTests.java deleted file mode 100644 index ae83b9f6be9..00000000000 --- a/src/test/java/org/elasticsearch/watcher/condition/simple/AlwaysTrueConditionTests.java +++ /dev/null @@ -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"); - } - -} diff --git a/src/test/java/org/elasticsearch/watcher/execution/ExecutionServiceTests.java b/src/test/java/org/elasticsearch/watcher/execution/ExecutionServiceTests.java index 4a21f09a4f7..10d05db78ba 100644 --- a/src/test/java/org/elasticsearch/watcher/execution/ExecutionServiceTests.java +++ b/src/test/java/org/elasticsearch/watcher/execution/ExecutionServiceTests.java @@ -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); diff --git a/src/test/java/org/elasticsearch/watcher/execution/ManualExecutionTests.java b/src/test/java/org/elasticsearch/watcher/execution/ManualExecutionTests.java index d52fbbeed2e..5194c740e32 100644 --- a/src/test/java/org/elasticsearch/watcher/execution/ManualExecutionTests.java +++ b/src/test/java/org/elasticsearch/watcher/execution/ManualExecutionTests.java @@ -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)); diff --git a/src/test/java/org/elasticsearch/watcher/history/HistoryStoreLifeCycleTest.java b/src/test/java/org/elasticsearch/watcher/history/HistoryStoreLifeCycleTest.java index ff1a05d0777..819072bf4b0 100644 --- a/src/test/java/org/elasticsearch/watcher/history/HistoryStoreLifeCycleTest.java +++ b/src/test/java/org/elasticsearch/watcher/history/HistoryStoreLifeCycleTest.java @@ -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); diff --git a/src/test/java/org/elasticsearch/watcher/history/HistoryStoreTests.java b/src/test/java/org/elasticsearch/watcher/history/HistoryStoreTests.java index 131a23597b0..5e321f63b86 100644 --- a/src/test/java/org/elasticsearch/watcher/history/HistoryStoreTests.java +++ b/src/test/java/org/elasticsearch/watcher/history/HistoryStoreTests.java @@ -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)); diff --git a/src/test/java/org/elasticsearch/watcher/history/WatchRecordTests.java b/src/test/java/org/elasticsearch/watcher/history/WatchRecordTests.java index c27da49cf39..1dc4355f8b2 100644 --- a/src/test/java/org/elasticsearch/watcher/history/WatchRecordTests.java +++ b/src/test/java/org/elasticsearch/watcher/history/WatchRecordTests.java @@ -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); diff --git a/src/test/java/org/elasticsearch/watcher/input/http/HttpInputTests.java b/src/test/java/org/elasticsearch/watcher/input/http/HttpInputTests.java index 173ab068eec..0db4e2e761b 100644 --- a/src/test/java/org/elasticsearch/watcher/input/http/HttpInputTests.java +++ b/src/test/java/org/elasticsearch/watcher/input/http/HttpInputTests.java @@ -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()), null, diff --git a/src/test/java/org/elasticsearch/watcher/input/search/SearchInputTests.java b/src/test/java/org/elasticsearch/watcher/input/search/SearchInputTests.java index 5dbb54c10ab..e195da1933e 100644 --- a/src/test/java/org/elasticsearch/watcher/input/search/SearchInputTests.java +++ b/src/test/java/org/elasticsearch/watcher/input/search/SearchInputTests.java @@ -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()), 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()), null, diff --git a/src/test/java/org/elasticsearch/watcher/license/LicenseIntegrationTests.java b/src/test/java/org/elasticsearch/watcher/license/LicenseIntegrationTests.java index 7a1e38dd618..6c717f44cdb 100644 --- a/src/test/java/org/elasticsearch/watcher/license/LicenseIntegrationTests.java +++ b/src/test/java/org/elasticsearch/watcher/license/LicenseIntegrationTests.java @@ -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(); diff --git a/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java b/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java index 0ec5ac366ab..30b7a54ff21 100644 --- a/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java +++ b/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java @@ -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, diff --git a/src/test/java/org/elasticsearch/watcher/test/integration/BootStrapTests.java b/src/test/java/org/elasticsearch/watcher/test/integration/BootStrapTests.java index 3866523110d..d793bf2afd9 100644 --- a/src/test/java/org/elasticsearch/watcher/test/integration/BootStrapTests.java +++ b/src/test/java/org/elasticsearch/watcher/test/integration/BootStrapTests.java @@ -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()), 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()), null, // metatdata diff --git a/src/test/java/org/elasticsearch/watcher/test/integration/WatchCrudTests.java b/src/test/java/org/elasticsearch/watcher/test/integration/WatchCrudTests.java index fa0fd39f9e5..1fdcdd12107 100644 --- a/src/test/java/org/elasticsearch/watcher/test/integration/WatchCrudTests.java +++ b/src/test/java/org/elasticsearch/watcher/test/integration/WatchCrudTests.java @@ -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(); diff --git a/src/test/java/org/elasticsearch/watcher/watch/WatchTests.java b/src/test/java/org/elasticsearch/watcher/watch/WatchTests.java index 010992b6aac..f5069eaae48 100644 --- a/src/test/java/org/elasticsearch/watcher/watch/WatchTests.java +++ b/src/test/java/org/elasticsearch/watcher/watch/WatchTests.java @@ -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 parsers = ImmutableMap.builder(); + private ConditionRegistry registry(ExecutableCondition condition) { + ImmutableMap.Builder 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()); } }