[script] utilize Script in ScriptTemplate & ScriptCondition

- also changed the `AbstractAlertsSingleNodeTests` to not reset after each test

Original commit: elastic/x-pack-elasticsearch@14377498e8
This commit is contained in:
uboness 2015-02-25 20:47:59 +02:00
parent de681481d1
commit 0f7dc295b3
13 changed files with 106 additions and 218 deletions

View File

@ -5,12 +5,12 @@
*/ */
package org.elasticsearch.alerts.condition.script; package org.elasticsearch.alerts.condition.script;
import org.elasticsearch.alerts.AlertsSettingsException;
import org.elasticsearch.alerts.ExecutionContext; import org.elasticsearch.alerts.ExecutionContext;
import org.elasticsearch.alerts.Payload;
import org.elasticsearch.alerts.condition.Condition; import org.elasticsearch.alerts.condition.Condition;
import org.elasticsearch.alerts.condition.ConditionException; import org.elasticsearch.alerts.condition.ConditionException;
import org.elasticsearch.alerts.support.Script;
import org.elasticsearch.alerts.support.init.proxy.ScriptServiceProxy; import org.elasticsearch.alerts.support.init.proxy.ScriptServiceProxy;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.ESLogger;
@ -18,10 +18,8 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.ExecutableScript;
import org.elasticsearch.script.ScriptService;
import java.io.IOException; import java.io.IOException;
import java.util.Locale;
/** /**
* This class executes a script against the ctx payload and returns a boolean * This class executes a script against the ctx payload and returns a boolean
@ -30,18 +28,13 @@ public class ScriptCondition extends Condition<ScriptCondition.Result> {
public static final String TYPE = "script"; public static final String TYPE = "script";
private final String script;
private final ScriptService.ScriptType scriptType;
private final String scriptLang;
private final ScriptServiceProxy scriptService; private final ScriptServiceProxy scriptService;
private final Script script;
public ScriptCondition(ESLogger logger, ScriptServiceProxy scriptService, String script, ScriptService.ScriptType scriptType, String scriptLang) { public ScriptCondition(ESLogger logger, ScriptServiceProxy scriptService, Script script) {
super(logger); super(logger);
this.script = script;
this.scriptType = scriptType;
this.scriptLang = scriptLang;
this.scriptService = scriptService; this.scriptService = scriptService;
this.script = script;
} }
@Override @Override
@ -49,13 +42,13 @@ public class ScriptCondition extends Condition<ScriptCondition.Result> {
return TYPE; return TYPE;
} }
@Override public Script script() {
public Result execute(ExecutionContext ctx) throws IOException { return script;
return processPayload(ctx.payload());
} }
protected Result processPayload(Payload payload) { @Override
ExecutableScript executable = scriptService.executable(scriptLang, script, scriptType, payload.data()); public Result execute(ExecutionContext ctx) throws IOException {
ExecutableScript executable = scriptService.executable(script.lang(), script.script(), script.type(), ctx.payload().data());
Object value = executable.run(); Object value = executable.run();
if (value instanceof Boolean) { if (value instanceof Boolean) {
return (Boolean) value ? Result.MET : Result.UNMET; return (Boolean) value ? Result.MET : Result.UNMET;
@ -65,17 +58,11 @@ public class ScriptCondition extends Condition<ScriptCondition.Result> {
@Override @Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(); return script.toXContent(builder, params);
builder.field(ScriptService.SCRIPT_INLINE.getPreferredName(), script);
builder.field(Parser.SCRIPT_TYPE_FIELD.getPreferredName(), scriptType);
builder.field(ScriptService.SCRIPT_LANG.getPreferredName(), scriptLang);
return builder.endObject();
} }
public static class Parser extends AbstractComponent implements Condition.Parser<Result, ScriptCondition> { public static class Parser extends AbstractComponent implements Condition.Parser<Result, ScriptCondition> {
public static ParseField SCRIPT_TYPE_FIELD = new ParseField("script_type");
private final ScriptServiceProxy scriptService; private final ScriptServiceProxy scriptService;
@Inject @Inject
@ -91,41 +78,12 @@ public class ScriptCondition extends Condition<ScriptCondition.Result> {
@Override @Override
public ScriptCondition parse(XContentParser parser) throws IOException { public ScriptCondition parse(XContentParser parser) throws IOException {
String scriptLang = null; try {
String script = null; Script script = Script.parse(parser);
ScriptService.ScriptType scriptType = ScriptService.ScriptType.INLINE; return new ScriptCondition(logger, scriptService, script);
} catch (Script.ParseException pe) {
String currentFieldName = null; throw new AlertsSettingsException("could not parse [script] condition", pe);
XContentParser.Token token;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if ((token.isValue() || token == XContentParser.Token.START_OBJECT) && currentFieldName != null) {
if (ScriptService.SCRIPT_ID.match(currentFieldName)) {
script = parser.text();
scriptType = ScriptService.ScriptType.INDEXED;
} else if (ScriptService.SCRIPT_INLINE.match(currentFieldName)) {
script = parser.text();
} else if (SCRIPT_TYPE_FIELD.match(currentFieldName)) {
String value = parser.text();
try {
scriptType = ScriptService.ScriptType.valueOf(value.toUpperCase(Locale.ROOT));
} catch (IllegalArgumentException iae) {
throw new ConditionException("could not parse [script] condition. unknown script type [" + value + "]");
}
} else if (ScriptService.SCRIPT_LANG.match(currentFieldName)) {
scriptLang = parser.text();
} else {
throw new ConditionException("could not parse [script] condition. unexpected field [" + currentFieldName + "]");
}
}
} }
if (script == null) {
throw new ConditionException("could not parse [script] condition. either [script] or [script_id] must be provided");
}
return new ScriptCondition(logger, scriptService, script, scriptType, scriptLang);
} }
@Override @Override

View File

@ -36,6 +36,10 @@ public class Script implements ToXContent {
this(script, ScriptService.ScriptType.INLINE, ScriptService.DEFAULT_LANG, Collections.<String, Object>emptyMap()); this(script, ScriptService.ScriptType.INLINE, ScriptService.DEFAULT_LANG, Collections.<String, Object>emptyMap());
} }
public Script(String script, ScriptService.ScriptType type, String lang) {
this(script, type, lang, Collections.<String, Object>emptyMap());
}
public Script(String script, ScriptService.ScriptType type, String lang, Map<String, Object> params) { public Script(String script, ScriptService.ScriptType type, String lang, Map<String, Object> params) {
this.script = script; this.script = script;
this.type = type; this.type = type;
@ -87,9 +91,9 @@ public class Script implements ToXContent {
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject() return builder.startObject()
.field(SCRIPT_FIELD.getPreferredName(), script) .field(SCRIPT_FIELD.getPreferredName(), script)
.field(TYPE_FIELD.getPreferredName(), script) .field(TYPE_FIELD.getPreferredName(), type)
.field(LANG_FIELD.getPreferredName(), lang) .field(LANG_FIELD.getPreferredName(), lang)
.field(PARAMS_FIELD.getPreferredName(), params) .field(PARAMS_FIELD.getPreferredName(), this.params)
.endObject(); .endObject();
} }

View File

@ -5,14 +5,9 @@
*/ */
package org.elasticsearch.alerts.support.template; package org.elasticsearch.alerts.support.template;
import org.elasticsearch.alerts.support.Script;
import org.elasticsearch.alerts.support.init.proxy.ScriptServiceProxy; import org.elasticsearch.alerts.support.init.proxy.ScriptServiceProxy;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.base.Function;
import org.elasticsearch.common.base.Joiner;
import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.collect.Collections2;
import org.elasticsearch.common.collect.ImmutableList;
import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
@ -25,7 +20,6 @@ import org.elasticsearch.script.ScriptService;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
import java.util.Map; import java.util.Map;
/** /**
@ -33,60 +27,33 @@ import java.util.Map;
*/ */
public class ScriptTemplate implements ToXContent, Template { public class ScriptTemplate implements ToXContent, Template {
static final ParseField TEXT_FIELD = new ParseField("script", "text");
static final ParseField LANG_FIELD = new ParseField("lang", "language", "script_lang");
static final ParseField TYPE_FIELD = new ParseField("type", "script_type");
static final ParseField PARAMS_FIELD = new ParseField("model", "params");
public static final String DEFAULT_LANG = "mustache"; public static final String DEFAULT_LANG = "mustache";
private final String text; private final Script script;
private final String lang;
private final ScriptService.ScriptType type;
private final Map<String, Object> params;
private final ScriptServiceProxy service; private final ScriptServiceProxy service;
public ScriptTemplate(ScriptServiceProxy service, String text) { public ScriptTemplate(ScriptServiceProxy service, String script) {
this(service, text, DEFAULT_LANG, ScriptService.ScriptType.INLINE, Collections.<String, Object>emptyMap()); this(service, new Script(script, ScriptService.ScriptType.INLINE, DEFAULT_LANG, Collections.<String, Object>emptyMap()));
} }
public ScriptTemplate(ScriptServiceProxy service, String text, String lang, ScriptService.ScriptType type) { public ScriptTemplate(ScriptServiceProxy service, Script script) {
this(service, text, lang, type, Collections.<String, Object>emptyMap()); this.script = script;
}
public ScriptTemplate(ScriptServiceProxy service, String text, String lang, ScriptService.ScriptType type, Map<String, Object> params) {
this.service = service; this.service = service;
this.text = text;
this.lang = lang;
this.type = type;
this.params = params;
} }
public String text() { public Script script() {
return text; return script;
}
public ScriptService.ScriptType type() {
return type;
}
public String lang() {
return lang;
}
public Map<String, Object> params() {
return params;
} }
@Override @Override
public String render(Map<String, Object> model) { public String render(Map<String, Object> model) {
Map<String, Object> mergedModel = new HashMap<>(); Map<String, Object> mergedModel = new HashMap<>();
mergedModel.putAll(params); mergedModel.putAll(script.params());
mergedModel.putAll(model); mergedModel.putAll(model);
ExecutableScript script = service.executable(lang, text, type, mergedModel); ExecutableScript executable = service.executable(script.lang(), script.script(), script.type(), mergedModel);
Object result = script.run(); Object result = executable.run();
if (result instanceof BytesReference) { if (result instanceof BytesReference) {
return ((BytesReference) script.run()).toUtf8(); return ((BytesReference) result).toUtf8();
} }
return result.toString(); return result.toString();
} }
@ -98,31 +65,19 @@ public class ScriptTemplate implements ToXContent, Template {
ScriptTemplate template = (ScriptTemplate) o; ScriptTemplate template = (ScriptTemplate) o;
if (!lang.equals(template.lang)) return false; if (!script.equals(template.script)) return false;
if (!params.equals(template.params)) return false;
if (!text.equals(template.text)) return false;
if (type != template.type) return false;
return true; return true;
} }
@Override @Override
public int hashCode() { public int hashCode() {
int result = text.hashCode(); return script.hashCode();
result = 31 * result + lang.hashCode();
result = 31 * result + type.hashCode();
result = 31 * result + params.hashCode();
return result;
} }
@Override @Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject() return script.toXContent(builder, params);
.field(TEXT_FIELD.getPreferredName(), text)
.field(TYPE_FIELD.getPreferredName(), type.name().toLowerCase(Locale.ROOT))
.field(LANG_FIELD.getPreferredName(), lang)
.field(PARAMS_FIELD.getPreferredName(), this.params)
.endObject();
} }
/** /**
@ -139,62 +94,18 @@ public class ScriptTemplate implements ToXContent, Template {
@Override @Override
public ScriptTemplate parse(XContentParser parser) throws IOException { public ScriptTemplate parse(XContentParser parser) throws IOException {
// we need to parse the string here, because the default script lang is different
// than the one Script assumes
if (parser.currentToken() == XContentParser.Token.VALUE_STRING) { if (parser.currentToken() == XContentParser.Token.VALUE_STRING) {
return new ScriptTemplate(scriptService, parser.text()); return new ScriptTemplate(scriptService, parser.text());
} }
if (parser.currentToken() != XContentParser.Token.START_OBJECT) { try {
throw new ParseException("expected either a string or an object, but found [" + parser.currentToken() + "] instead"); Script script = Script.parse(parser);
return new ScriptTemplate(scriptService, script);
} catch (Script.ParseException pe) {
throw new ParseException("could not parse script template", pe);
} }
String text = null;
ScriptService.ScriptType type = ScriptService.ScriptType.INLINE;
String lang = DEFAULT_LANG;
ImmutableMap.Builder<String, Object> params = ImmutableMap.builder();
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 (TEXT_FIELD.match(currentFieldName)) {
if (token.isValue()) {
text = parser.text();
} else {
throw new ParseException("expected a string value for [" + currentFieldName + "], but found [" + token + "] instead");
}
} else if (LANG_FIELD.match(currentFieldName)) {
if (token == XContentParser.Token.VALUE_STRING) {
lang = parser.text();
} else {
throw new ParseException("expected a string value for [" + currentFieldName + "], but found [" + token + "] instead");
}
} else if (TYPE_FIELD.match(currentFieldName)) {
if (token == XContentParser.Token.VALUE_STRING) {
String value = parser.text();
try {
type = ScriptService.ScriptType.valueOf(value.toUpperCase(Locale.ROOT));
} catch (IllegalArgumentException iae) {
String typeOptions = Joiner.on(",").join(Collections2.transform(ImmutableList.copyOf(ScriptService.ScriptType.values()), new Function<ScriptService.ScriptType, String>() {
@Override
public String apply(ScriptService.ScriptType scriptType) {
return scriptType.name().toLowerCase(Locale.ROOT);
}
}));
throw new ParseException("unknown template script type [" + currentFieldName + "]. type can only be on of: [" + typeOptions + "]");
}
}
} else if (PARAMS_FIELD.match(currentFieldName)) {
if (token != XContentParser.Token.START_OBJECT) {
throw new ParseException("expected an object for [" + currentFieldName + "], but found [" + token + "]");
}
params.putAll(parser.map());
} else {
throw new ParseException("unexpected field [" + currentFieldName + "]");
}
}
if (text == null) {
throw new ParseException("missing required field [" + TEXT_FIELD.getPreferredName() + "]");
}
return new ScriptTemplate(scriptService, text, lang, type, params.build());
} }
} }

View File

@ -28,6 +28,10 @@ public interface Template extends ToXContent {
public ParseException(String msg) { public ParseException(String msg) {
super(msg); super(msg);
} }
public ParseException(String msg, Throwable cause) {
super(msg, cause);
}
} }
} }

View File

@ -24,6 +24,7 @@ import org.elasticsearch.alerts.history.HistoryStore;
import org.elasticsearch.alerts.input.search.SearchInput; import org.elasticsearch.alerts.input.search.SearchInput;
import org.elasticsearch.alerts.scheduler.schedule.CronSchedule; import org.elasticsearch.alerts.scheduler.schedule.CronSchedule;
import org.elasticsearch.alerts.support.AlertUtils; import org.elasticsearch.alerts.support.AlertUtils;
import org.elasticsearch.alerts.support.Script;
import org.elasticsearch.alerts.support.init.proxy.ClientProxy; import org.elasticsearch.alerts.support.init.proxy.ClientProxy;
import org.elasticsearch.alerts.support.init.proxy.ScriptServiceProxy; import org.elasticsearch.alerts.support.init.proxy.ScriptServiceProxy;
import org.elasticsearch.alerts.support.template.ScriptTemplate; import org.elasticsearch.alerts.support.template.ScriptTemplate;
@ -206,7 +207,7 @@ public abstract class AbstractAlertingTests extends ElasticsearchIntegrationTest
new CronSchedule("0/5 * * * * ? *"), new CronSchedule("0/5 * * * * ? *"),
new SearchInput(logger, scriptService(), ClientProxy.of(client()), new SearchInput(logger, scriptService(), ClientProxy.of(client()),
conditionRequest), conditionRequest),
new ScriptCondition(logger, scriptService(), "return true", ScriptService.ScriptType.INLINE, "groovy"), new ScriptCondition(logger, scriptService(), new Script("return true")),
new SearchTransform(logger, scriptService(), ClientProxy.of(client()), transformRequest), new Actions(actions), metadata, new Alert.Status(), new TimeValue(0) new SearchTransform(logger, scriptService(), ClientProxy.of(client()), transformRequest), new Actions(actions), metadata, new Alert.Status(), new TimeValue(0)
); );
} }

View File

@ -20,6 +20,7 @@ import org.elasticsearch.alerts.history.FiredAlert;
import org.elasticsearch.alerts.history.HistoryStore; import org.elasticsearch.alerts.history.HistoryStore;
import org.elasticsearch.alerts.input.search.SearchInput; import org.elasticsearch.alerts.input.search.SearchInput;
import org.elasticsearch.alerts.scheduler.schedule.CronSchedule; import org.elasticsearch.alerts.scheduler.schedule.CronSchedule;
import org.elasticsearch.alerts.support.Script;
import org.elasticsearch.alerts.support.init.proxy.ClientProxy; import org.elasticsearch.alerts.support.init.proxy.ClientProxy;
import org.elasticsearch.alerts.transform.SearchTransform; import org.elasticsearch.alerts.transform.SearchTransform;
import org.elasticsearch.alerts.transport.actions.ack.AckAlertResponse; import org.elasticsearch.alerts.transport.actions.ack.AckAlertResponse;
@ -30,7 +31,6 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHit;
import org.junit.Test; import org.junit.Test;
@ -69,7 +69,7 @@ public class AlertThrottleTests extends AbstractAlertingTests {
new CronSchedule("0/5 * * * * ? *"), new CronSchedule("0/5 * * * * ? *"),
new SearchInput(logger, scriptService(), ClientProxy.of(client()), new SearchInput(logger, scriptService(), ClientProxy.of(client()),
request), request),
new ScriptCondition(logger, scriptService(), "hits.total > 0", ScriptService.ScriptType.INLINE, "groovy"), new ScriptCondition(logger, scriptService(), new Script("hits.total > 0")),
new SearchTransform(logger, scriptService(), ClientProxy.of(client()), request), new Actions(actions), null, new Alert.Status(), new TimeValue(0) new SearchTransform(logger, scriptService(), ClientProxy.of(client()), request), new Actions(actions), null, new Alert.Status(), new TimeValue(0)
); );
@ -148,12 +148,9 @@ public class AlertThrottleTests extends AbstractAlertingTests {
"test-time-throttle", "test-time-throttle",
new CronSchedule("0/5 * * * * ? *"), new CronSchedule("0/5 * * * * ? *"),
new SearchInput(logger, scriptService(), ClientProxy.of(client()), request), new SearchInput(logger, scriptService(), ClientProxy.of(client()), request),
new ScriptCondition(logger, scriptService(), "hits.total > 0", ScriptService.ScriptType.INLINE, "groovy"), new ScriptCondition(logger, scriptService(), new Script("hits.total > 0")),
new SearchTransform(logger, scriptService(), ClientProxy.of(client()), request), new SearchTransform(logger, scriptService(), ClientProxy.of(client()), request),
new Actions(actions), null, new Alert.Status(), new TimeValue(10, TimeUnit.SECONDS) new Actions(actions), null, new Alert.Status(), new TimeValue(10, TimeUnit.SECONDS));
);
XContentBuilder jsonBuilder = XContentFactory.jsonBuilder(); XContentBuilder jsonBuilder = XContentFactory.jsonBuilder();
alert.toXContent(jsonBuilder, ToXContent.EMPTY_PARAMS); alert.toXContent(jsonBuilder, ToXContent.EMPTY_PARAMS);
@ -205,8 +202,8 @@ public class AlertThrottleTests extends AbstractAlertingTests {
while(System.currentTimeMillis() < start + value.getMillis()){ while(System.currentTimeMillis() < start + value.getMillis()){
try{ try{
Thread.sleep(value.getMillis() - (System.currentTimeMillis() - start)); Thread.sleep(value.getMillis() - (System.currentTimeMillis() - start));
} catch (InterruptedException ie){ } catch (InterruptedException ie) {
logger.error("interrupted", ie);
} }
} }
} }

View File

@ -16,6 +16,7 @@ import org.elasticsearch.alerts.history.FiredAlert;
import org.elasticsearch.alerts.history.HistoryStore; import org.elasticsearch.alerts.history.HistoryStore;
import org.elasticsearch.alerts.input.search.SearchInput; import org.elasticsearch.alerts.input.search.SearchInput;
import org.elasticsearch.alerts.scheduler.schedule.CronSchedule; import org.elasticsearch.alerts.scheduler.schedule.CronSchedule;
import org.elasticsearch.alerts.support.Script;
import org.elasticsearch.alerts.support.init.proxy.ClientProxy; import org.elasticsearch.alerts.support.init.proxy.ClientProxy;
import org.elasticsearch.alerts.transform.SearchTransform; import org.elasticsearch.alerts.transform.SearchTransform;
import org.elasticsearch.alerts.transport.actions.put.PutAlertResponse; import org.elasticsearch.alerts.transport.actions.put.PutAlertResponse;
@ -27,7 +28,6 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.test.junit.annotations.TestLogging; import org.elasticsearch.test.junit.annotations.TestLogging;
import org.junit.Test; import org.junit.Test;
@ -80,7 +80,7 @@ public class BootStrapTest extends AbstractAlertingTests {
"test-serialization", "test-serialization",
new CronSchedule("0/5 * * * * ? 2035"), //Set this into the future so we don't get any extra runs 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), new SearchInput(logger, scriptService(), ClientProxy.of(client()), searchRequest),
new ScriptCondition(logger, scriptService(), "return true", ScriptService.ScriptType.INLINE, "groovy"), new ScriptCondition(logger, scriptService(), new Script("return true")),
new SearchTransform(logger, scriptService(), ClientProxy.of(client()), searchRequest), new SearchTransform(logger, scriptService(), ClientProxy.of(client()), searchRequest),
new Actions(new ArrayList<Action>()), null, new Alert.Status(), new TimeValue(0) new Actions(new ArrayList<Action>()), null, new Alert.Status(), new TimeValue(0)
@ -139,7 +139,7 @@ public class BootStrapTest extends AbstractAlertingTests {
new CronSchedule("0/5 * * * * ? 2035"), //Set a cron schedule far into the future so this alert is never scheduled new CronSchedule("0/5 * * * * ? 2035"), //Set a cron schedule far into the future so this alert is never scheduled
new SearchInput(logger, scriptService(), ClientProxy.of(client()), new SearchInput(logger, scriptService(), ClientProxy.of(client()),
searchRequest), searchRequest),
new ScriptCondition(logger, scriptService(), "return true", ScriptService.ScriptType.INLINE, "groovy"), new ScriptCondition(logger, scriptService(), new Script("return true")),
new SearchTransform(logger, scriptService(), ClientProxy.of(client()), searchRequest), new SearchTransform(logger, scriptService(), ClientProxy.of(client()), searchRequest),
new Actions(new ArrayList<Action>()), new Actions(new ArrayList<Action>()),
null, null,

View File

@ -13,6 +13,7 @@ import org.elasticsearch.alerts.actions.index.IndexAction;
import org.elasticsearch.alerts.condition.script.ScriptCondition; import org.elasticsearch.alerts.condition.script.ScriptCondition;
import org.elasticsearch.alerts.input.search.SearchInput; import org.elasticsearch.alerts.input.search.SearchInput;
import org.elasticsearch.alerts.scheduler.schedule.CronSchedule; import org.elasticsearch.alerts.scheduler.schedule.CronSchedule;
import org.elasticsearch.alerts.support.Script;
import org.elasticsearch.alerts.support.init.proxy.ClientProxy; import org.elasticsearch.alerts.support.init.proxy.ClientProxy;
import org.elasticsearch.alerts.transform.SearchTransform; import org.elasticsearch.alerts.transform.SearchTransform;
import org.elasticsearch.alerts.transport.actions.put.PutAlertResponse; import org.elasticsearch.alerts.transport.actions.put.PutAlertResponse;
@ -61,7 +62,7 @@ public class TransformSearchTest extends AbstractAlertingTests {
new CronSchedule("0/5 * * * * ? *"), new CronSchedule("0/5 * * * * ? *"),
new SearchInput(logger, scriptService(), ClientProxy.of(client()), new SearchInput(logger, scriptService(), ClientProxy.of(client()),
conditionRequest), conditionRequest),
new ScriptCondition(logger, scriptService(), "return true", ScriptService.ScriptType.INLINE, "groovy"), new ScriptCondition(logger, scriptService(), new Script("return true")),
new SearchTransform(logger, scriptService(), ClientProxy.of(client()), transformRequest), new SearchTransform(logger, scriptService(), ClientProxy.of(client()), transformRequest),
new Actions(actions), metadata, new Alert.Status(), new TimeValue(0) new Actions(actions), metadata, new Alert.Status(), new TimeValue(0)
); );

View File

@ -14,6 +14,7 @@ import org.elasticsearch.alerts.condition.script.ScriptCondition;
import org.elasticsearch.alerts.input.Input; import org.elasticsearch.alerts.input.Input;
import org.elasticsearch.alerts.input.search.SearchInput; import org.elasticsearch.alerts.input.search.SearchInput;
import org.elasticsearch.alerts.scheduler.schedule.CronSchedule; import org.elasticsearch.alerts.scheduler.schedule.CronSchedule;
import org.elasticsearch.alerts.support.Script;
import org.elasticsearch.alerts.support.init.proxy.ClientProxy; import org.elasticsearch.alerts.support.init.proxy.ClientProxy;
import org.elasticsearch.alerts.transform.SearchTransform; import org.elasticsearch.alerts.transform.SearchTransform;
import org.elasticsearch.alerts.transport.actions.delete.DeleteAlertRequest; import org.elasticsearch.alerts.transport.actions.delete.DeleteAlertRequest;
@ -60,7 +61,7 @@ public class ActionsTest extends AbstractAlertingTests {
Input alertInput = new SearchInput(logger, scriptService(), ClientProxy.of(client()), Input alertInput = new SearchInput(logger, scriptService(), ClientProxy.of(client()),
createConditionSearchRequest()); createConditionSearchRequest());
Condition alertCondition = new ScriptCondition(logger, scriptService(), "return true", ScriptService.ScriptType.INLINE, "groovy"); Condition alertCondition = new ScriptCondition(logger, scriptService(), new Script("return true"));

View File

@ -163,21 +163,21 @@ public class EmailActionTests extends ElasticsearchTestCase {
} }
if (subject != null) { if (subject != null) {
if (randomBoolean()) { if (randomBoolean()) {
builder.field("subject", subject.text()); builder.field("subject", subject.script().script());
} else { } else {
builder.field("subject", subject); builder.field("subject", subject);
} }
} }
if (textBody != null) { if (textBody != null) {
if (randomBoolean()) { if (randomBoolean()) {
builder.field("text_body", textBody.text()); builder.field("text_body", textBody.script().script());
} else { } else {
builder.field("text_body", textBody); builder.field("text_body", textBody);
} }
} }
if (htmlBody != null) { if (htmlBody != null) {
if (randomBoolean()) { if (randomBoolean()) {
builder.field("html_body", htmlBody.text()); builder.field("html_body", htmlBody.script().script());
} else { } else {
builder.field("html_body", htmlBody); builder.field("html_body", htmlBody);
} }

View File

@ -7,8 +7,11 @@ package org.elasticsearch.alerts.condition.script;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.alerts.AlertsSettingsException;
import org.elasticsearch.alerts.ExecutionContext;
import org.elasticsearch.alerts.Payload; import org.elasticsearch.alerts.Payload;
import org.elasticsearch.alerts.condition.ConditionException; import org.elasticsearch.alerts.condition.ConditionException;
import org.elasticsearch.alerts.support.Script;
import org.elasticsearch.alerts.support.init.proxy.ScriptServiceProxy; import org.elasticsearch.alerts.support.init.proxy.ScriptServiceProxy;
import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
@ -32,6 +35,7 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.mockito.Mockito.*;
/** /**
*/ */
@ -53,9 +57,11 @@ public class ScriptConditionTests extends ElasticsearchTestCase {
@Test @Test
public void testExecute() throws Exception { public void testExecute() throws Exception {
ScriptServiceProxy scriptService = getScriptServiceProxy(tp); ScriptServiceProxy scriptService = getScriptServiceProxy(tp);
ScriptCondition condition = new ScriptCondition(logger, scriptService, "hits.total > 1", ScriptService.ScriptType.INLINE, "groovy"); ScriptCondition condition = new ScriptCondition(logger, scriptService, new Script("hits.total > 1"));
SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500l, new ShardSearchFailure[0]); SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500l, new ShardSearchFailure[0]);
assertFalse(condition.processPayload(new Payload.ActionResponse(response)).met()); ExecutionContext ctx = mock(ExecutionContext.class);
when(ctx.payload()).thenReturn(new Payload.ActionResponse(response));
assertFalse(condition.execute(ctx).met());
} }
@Test @Test
@ -64,31 +70,35 @@ public class ScriptConditionTests extends ElasticsearchTestCase {
XContentBuilder builder = createConditionContent("hits.total > 1", null, null); XContentBuilder builder = createConditionContent("hits.total > 1", null, null);
XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes()); XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
parser.nextToken();
ScriptCondition condition = conditionParser.parse(parser); ScriptCondition condition = conditionParser.parse(parser);
SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500l, new ShardSearchFailure[0]); SearchResponse response = new SearchResponse(InternalSearchResponse.empty(), "", 3, 3, 500l, new ShardSearchFailure[0]);
ExecutionContext ctx = mock(ExecutionContext.class);
when(ctx.payload()).thenReturn(new Payload.ActionResponse(response));
assertFalse(condition.processPayload(new Payload.ActionResponse(response)).met()); assertFalse(condition.execute(ctx).met());
builder = createConditionContent("return true", null, null); builder = createConditionContent("return true", null, null);
parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes()); parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
parser.nextToken();
condition = conditionParser.parse(parser); condition = conditionParser.parse(parser);
assertTrue(condition.processPayload(new Payload.ActionResponse(response)).met()); reset(ctx);
when(ctx.payload()).thenReturn(new Payload.ActionResponse(response));
assertTrue(condition.execute(ctx).met());
} }
@Test(expected = ConditionException.class) @Test(expected = AlertsSettingsException.class)
public void testParser_InValid() throws Exception { public void testParser_InValid() throws Exception {
ScriptCondition.Parser conditionParser = new ScriptCondition.Parser(ImmutableSettings.settingsBuilder().build(), getScriptServiceProxy(tp)); ScriptCondition.Parser conditionParser = new ScriptCondition.Parser(ImmutableSettings.settingsBuilder().build(), getScriptServiceProxy(tp));
XContentBuilder builder = XContentFactory.jsonBuilder(); XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject().endObject(); builder.startObject().endObject();
XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes()); XContentParser parser = XContentFactory.xContent(builder.bytes()).createParser(builder.bytes());
try { parser.nextToken();
conditionParser.parse(parser); conditionParser.parse(parser);
} catch (Throwable t) {
throw t;
}
fail("expected a condition exception trying to parse an invalid condition XContent"); fail("expected a condition exception trying to parse an invalid condition XContent");
} }
@ -140,20 +150,15 @@ public class ScriptConditionTests extends ElasticsearchTestCase {
} }
private static XContentBuilder createConditionContent(String script, String scriptLang, ScriptService.ScriptType scriptType) throws IOException { private static XContentBuilder createConditionContent(String script, String scriptLang, ScriptService.ScriptType scriptType) throws IOException {
XContentBuilder jsonBuilder = jsonBuilder(); XContentBuilder builder = jsonBuilder().startObject();
jsonBuilder.startObject(); builder.field("script", script);
jsonBuilder.field("script");
jsonBuilder.startObject();
jsonBuilder.field("script", script);
if (scriptLang != null) { if (scriptLang != null) {
jsonBuilder.field("script_lang", scriptLang); builder.field("lang", scriptLang);
} }
if (scriptType != null) { if (scriptType != null) {
jsonBuilder.field("script_type", scriptType.toString()); builder.field("type", scriptType.toString());
} }
jsonBuilder.endObject(); return builder.endObject();
jsonBuilder.endObject();
return jsonBuilder;
} }

View File

@ -5,6 +5,7 @@
*/ */
package org.elasticsearch.alerts.support.template; package org.elasticsearch.alerts.support.template;
import org.elasticsearch.alerts.support.Script;
import org.elasticsearch.alerts.support.init.proxy.ScriptServiceProxy; import org.elasticsearch.alerts.support.init.proxy.ScriptServiceProxy;
import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.collect.ImmutableMap; import org.elasticsearch.common.collect.ImmutableMap;
@ -51,7 +52,8 @@ public class ScriptTemplateTests extends ElasticsearchTestCase {
when(script.run()).thenReturn("rendered_text"); when(script.run()).thenReturn("rendered_text");
when(proxy.executable(lang, templateText, scriptType, merged)).thenReturn(script); when(proxy.executable(lang, templateText, scriptType, merged)).thenReturn(script);
ScriptTemplate template = new ScriptTemplate(proxy, templateText, lang, scriptType, params); Script script = new Script(templateText, scriptType, lang, params);
ScriptTemplate template = new ScriptTemplate(proxy, script);
assertThat(template.render(model), is("rendered_text")); assertThat(template.render(model), is("rendered_text"));
} }
@ -67,7 +69,8 @@ public class ScriptTemplateTests extends ElasticsearchTestCase {
when(script.run()).thenReturn("rendered_text"); when(script.run()).thenReturn("rendered_text");
when(proxy.executable(lang, templateText, scriptType, model)).thenReturn(script); when(proxy.executable(lang, templateText, scriptType, model)).thenReturn(script);
ScriptTemplate template = new ScriptTemplate(proxy, templateText, lang, scriptType, params); Script script = new Script(templateText, scriptType, lang, params);
ScriptTemplate template = new ScriptTemplate(proxy, script);
assertThat(template.render(model), is("rendered_text")); assertThat(template.render(model), is("rendered_text"));
} }
@ -87,13 +90,14 @@ public class ScriptTemplateTests extends ElasticsearchTestCase {
public void testParser() throws Exception { public void testParser() throws Exception {
ScriptTemplate.Parser templateParser = new ScriptTemplate.Parser(ImmutableSettings.EMPTY, proxy); ScriptTemplate.Parser templateParser = new ScriptTemplate.Parser(ImmutableSettings.EMPTY, proxy);
ScriptTemplate template = new ScriptTemplate(proxy, "_template", "_lang", randomScriptType(), ImmutableMap.<String, Object>of("param_key", "param_val")); Script script = new Script("_template", randomScriptType(), "_lang", ImmutableMap.<String, Object>of("param_key", "param_val"));
ScriptTemplate template = new ScriptTemplate(proxy, script);
XContentBuilder builder = jsonBuilder().startObject() XContentBuilder builder = jsonBuilder().startObject()
.field(randomFrom("lang", "script_lang"), template.lang()) .field(randomFrom("lang"), template.script().lang())
.field(randomFrom("script", "text"), template.text()) .field(randomFrom("script"), template.script().script())
.field(randomFrom("type", "script_type"), template.type().name()) .field(randomFrom("type"), template.script().type().name())
.field(randomFrom("params", "model"), template.params()) .field(randomFrom("params"), template.script().params())
.endObject(); .endObject();
BytesReference bytes = builder.bytes(); BytesReference bytes = builder.bytes();
XContentParser parser = JsonXContent.jsonXContent.createParser(bytes); XContentParser parser = JsonXContent.jsonXContent.createParser(bytes);
@ -107,10 +111,12 @@ public class ScriptTemplateTests extends ElasticsearchTestCase {
public void testParser_ParserSelfGenerated() throws Exception { public void testParser_ParserSelfGenerated() throws Exception {
ScriptTemplate.Parser templateParser = new ScriptTemplate.Parser(ImmutableSettings.EMPTY, proxy); ScriptTemplate.Parser templateParser = new ScriptTemplate.Parser(ImmutableSettings.EMPTY, proxy);
ScriptTemplate template = new ScriptTemplate(proxy, "_template", "_lang", randomScriptType(), ImmutableMap.<String, Object>of("param_key", "param_val")); Script script = new Script("_template", randomScriptType(), "_lang", ImmutableMap.<String, Object>of("param_key", "param_val"));
ScriptTemplate template = new ScriptTemplate(proxy, script);
XContentBuilder builder = jsonBuilder().value(template); XContentBuilder builder = jsonBuilder().value(template);
BytesReference bytes = builder.bytes(); BytesReference bytes = builder.bytes();
System.out.println(bytes.toUtf8());
XContentParser parser = JsonXContent.jsonXContent.createParser(bytes); XContentParser parser = JsonXContent.jsonXContent.createParser(bytes);
parser.nextToken(); parser.nextToken();
ScriptTemplate parsed = templateParser.parse(parser); ScriptTemplate parsed = templateParser.parse(parser);

View File

@ -42,7 +42,7 @@ public abstract class AbstractAlertsSingleNodeTests extends ElasticsearchSingleN
@Override @Override
protected boolean resetNodeAfterTest() { protected boolean resetNodeAfterTest() {
return true; return false;
} }
protected IndexResponse index(String index, String type, String id) { protected IndexResponse index(String index, String type, String id) {