From 83757888391c7e2a5aed6216316352718b718e50 Mon Sep 17 00:00:00 2001 From: Brian Murphy Date: Thu, 4 Dec 2014 14:30:04 +0000 Subject: [PATCH 1/2] Merge result from rebase. Original commit: elastic/x-pack-elasticsearch@7e091273da0fb5b1bb01c2ed0ffe6d0cb87acbce --- .../java/org/elasticsearch/alerts/Alert.java | 40 +++++++--- .../elasticsearch/alerts/AlertManager.java | 24 +++++- .../org/elasticsearch/alerts/AlertUtils.java | 55 ++++++++++++-- .../org/elasticsearch/alerts/AlertsStore.java | 9 ++- .../alerts/actions/AlertActionEntry.java | 33 ++++---- .../alerts/actions/AlertActionManager.java | 6 +- .../alerts/actions/AlertActionRegistry.java | 4 +- .../actions/EmailAlertActionFactory.java | 10 +-- .../actions/IndexAlertActionFactory.java | 2 +- .../alerts/triggers/TriggerManager.java | 39 +--------- .../alerts/triggers/TriggerResult.java | 66 +++++++++++++--- src/main/resources/alerts.json | 7 +- .../alerts/AbstractAlertingTests.java | 4 +- .../alerts/AlertSerializationTest.java | 25 ++++--- .../alerts/AlertThrottleTests.java | 7 +- .../alerts/PayloadSearchTest.java | 75 +++++++++++++++++++ .../alerts/actions/AlertActionsTest.java | 7 +- 17 files changed, 297 insertions(+), 116 deletions(-) create mode 100644 src/test/java/org/elasticsearch/alerts/PayloadSearchTest.java diff --git a/src/main/java/org/elasticsearch/alerts/Alert.java b/src/main/java/org/elasticsearch/alerts/Alert.java index e9a0dbc218d..051aa121978 100644 --- a/src/main/java/org/elasticsearch/alerts/Alert.java +++ b/src/main/java/org/elasticsearch/alerts/Alert.java @@ -22,7 +22,7 @@ import java.util.Map; public class Alert implements ToXContent { private String alertName; - private SearchRequest searchRequest; + private SearchRequest triggerSearchRequest; private AlertTrigger trigger; private List actions; private String schedule; @@ -30,7 +30,10 @@ public class Alert implements ToXContent { private TimeValue throttlePeriod = new TimeValue(0); private DateTime timeLastActionExecuted = null; private AlertAckState ackState = AlertAckState.NOT_ACKABLE; - private Map metadata = null; + + //Optional + private Map metadata; + private SearchRequest payloadSearchRequest; private transient long version; private transient XContentType contentType; @@ -40,9 +43,9 @@ public class Alert implements ToXContent { } - public Alert(String alertName, SearchRequest searchRequest, AlertTrigger trigger, List actions, String schedule, DateTime lastExecuteTime, long version, TimeValue throttlePeriod, AlertAckState ackState) { + public Alert(String alertName, SearchRequest triggerSearchRequest, AlertTrigger trigger, List actions, String schedule, DateTime lastExecuteTime, long version, TimeValue throttlePeriod, AlertAckState ackState) { this.alertName = alertName; - this.searchRequest = searchRequest; + this.triggerSearchRequest = triggerSearchRequest; this.trigger = trigger; this.actions = actions; this.schedule = schedule; @@ -56,8 +59,14 @@ public class Alert implements ToXContent { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); builder.field(AlertsStore.SCHEDULE_FIELD.getPreferredName(), schedule); - builder.field(AlertsStore.REQUEST_FIELD.getPreferredName()); - AlertUtils.writeSearchRequest(searchRequest, builder, params); + builder.field(AlertsStore.TRIGGER_REQUEST_FIELD.getPreferredName()); + AlertUtils.writeSearchRequest(triggerSearchRequest, builder, params); + + if (payloadSearchRequest != null) { + builder.field(AlertsStore.PAYLOAD_REQUEST_FIELD.getPreferredName()); + AlertUtils.writeSearchRequest(payloadSearchRequest, builder, params); + } + builder.field(AlertsStore.THROTTLE_PERIOD_FIELD.getPreferredName(), throttlePeriod.millis()); builder.field(AlertsStore.ACK_STATE_FIELD.getPreferredName(), ackState.toString()); @@ -138,12 +147,12 @@ public class Alert implements ToXContent { /** * @return The search request that runs when the alert runs by the sc */ - public SearchRequest getSearchRequest() { - return searchRequest; + public SearchRequest getTriggerSearchRequest() { + return triggerSearchRequest; } - void setSearchRequest(SearchRequest searchRequest) { - this.searchRequest = searchRequest; + public void setTriggerSearchRequest(SearchRequest triggerSearchRequest) { + this.triggerSearchRequest = triggerSearchRequest; } /** @@ -223,6 +232,17 @@ public class Alert implements ToXContent { this.metadata = metadata; } + /** + * @return the search request that will be run for actions + */ + public SearchRequest getPayloadSearchRequest() { + return payloadSearchRequest; + } + + public void setPayloadSearchRequest(SearchRequest payloadSearchRequest) { + this.payloadSearchRequest = payloadSearchRequest; + } + @Override public boolean equals(Object o) { diff --git a/src/main/java/org/elasticsearch/alerts/AlertManager.java b/src/main/java/org/elasticsearch/alerts/AlertManager.java index a2b4f94dcf3..76f93ae2030 100644 --- a/src/main/java/org/elasticsearch/alerts/AlertManager.java +++ b/src/main/java/org/elasticsearch/alerts/AlertManager.java @@ -10,12 +10,15 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchIllegalStateException; import org.elasticsearch.action.delete.DeleteResponse; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.alerts.actions.AlertActionEntry; import org.elasticsearch.alerts.actions.AlertActionManager; import org.elasticsearch.alerts.actions.AlertActionRegistry; import org.elasticsearch.alerts.scheduler.AlertScheduler; import org.elasticsearch.alerts.triggers.TriggerManager; import org.elasticsearch.alerts.triggers.TriggerResult; +import org.elasticsearch.client.Client; import org.elasticsearch.cluster.ClusterChangedEvent; import org.elasticsearch.cluster.ClusterService; import org.elasticsearch.cluster.ClusterState; @@ -28,14 +31,20 @@ import org.elasticsearch.common.joda.time.DateTime; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.KeyedLock; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.gateway.GatewayService; import org.elasticsearch.indices.IndicesService; +import org.elasticsearch.script.ScriptService; import org.elasticsearch.threadpool.ThreadPool; import java.io.IOException; +import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicReference; +import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; + public class AlertManager extends AbstractComponent { private final AlertScheduler scheduler; @@ -45,6 +54,8 @@ public class AlertManager extends AbstractComponent { private final AlertActionRegistry actionRegistry; private final ThreadPool threadPool; private final ClusterService clusterService; + private final ScriptService scriptService; + private final Client client; private final KeyedLock alertLock = new KeyedLock<>(); private final AtomicReference state = new AtomicReference<>(State.STOPPED); @@ -53,7 +64,7 @@ public class AlertManager extends AbstractComponent { @Inject public AlertManager(Settings settings, ClusterService clusterService, AlertScheduler scheduler, AlertsStore alertsStore, IndicesService indicesService, TriggerManager triggerManager, AlertActionManager actionManager, - AlertActionRegistry actionRegistry, ThreadPool threadPool) { + AlertActionRegistry actionRegistry, ThreadPool threadPool, ScriptService scriptService, Client client) { super(settings); this.scheduler = scheduler; this.threadPool = threadPool; @@ -64,6 +75,8 @@ public class AlertManager extends AbstractComponent { this.actionManager.setAlertManager(this); this.actionRegistry = actionRegistry; this.clusterService = clusterService; + this.scriptService = scriptService; + this.client = client; clusterService.add(new AlertsClusterStateListener()); manuallyStopped = !settings.getAsBoolean("alerts.start_immediately", true); // Close if the indices service is being stopped, so we don't run into search failures (locally) that will @@ -140,9 +153,18 @@ public class AlertManager extends AbstractComponent { throw new ElasticsearchException("Alert is not available"); } TriggerResult triggerResult = triggerManager.isTriggered(alert, entry.getScheduledTime(), entry.getFireTime()); + if (triggerResult.isTriggered()) { triggerResult.setThrottled(isActionThrottled(alert)); if (!triggerResult.isThrottled()) { + if (alert.getPayloadSearchRequest() != null) { + SearchRequest payloadRequest = AlertUtils.createSearchRequestWithTimes(alert.getPayloadSearchRequest(), entry.getScheduledTime(), entry.getFireTime(), scriptService); + SearchResponse payloadResponse = client.search(payloadRequest).actionGet(); + triggerResult.setPayloadRequest(payloadRequest); + XContentBuilder builder = jsonBuilder().startObject().value(payloadResponse).endObject(); + Map responseMap = XContentHelper.convertToMap(builder.bytes(), false).v2(); + triggerResult.setPayloadResponse(responseMap); + } actionRegistry.doAction(alert, triggerResult); alert.setTimeLastActionExecuted(entry.getScheduledTime()); if (alert.getAckState() == AlertAckState.NOT_TRIGGERED) { diff --git a/src/main/java/org/elasticsearch/alerts/AlertUtils.java b/src/main/java/org/elasticsearch/alerts/AlertUtils.java index d878efc0a3c..17943e765ac 100644 --- a/src/main/java/org/elasticsearch/alerts/AlertUtils.java +++ b/src/main/java/org/elasticsearch/alerts/AlertUtils.java @@ -6,38 +6,79 @@ package org.elasticsearch.alerts; import org.elasticsearch.ElasticsearchIllegalArgumentException; +import org.elasticsearch.ElasticsearchIllegalStateException; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchType; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.common.Strings; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.collect.MapBuilder; +import org.elasticsearch.common.joda.FormatDateTimeFormatter; +import org.elasticsearch.common.joda.time.DateTime; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.index.mapper.core.DateFieldMapper; +import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.ScriptService; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; +import java.util.*; /** */ public final class AlertUtils { public final static IndicesOptions DEFAULT_INDICES_OPTIONS = IndicesOptions.lenientExpandOpen(); - public final static SearchType DEFAULT_SEARCH_TYPE = SearchType.COUNT; + public final static SearchType DEFAULT_TRIGGER_SEARCH_TYPE = SearchType.COUNT; + public final static SearchType DEFAULT_PAYLOAD_SEARCH_TYPE = SearchType.DFS_QUERY_AND_FETCH; + + private static final String FIRE_TIME_VARIABLE_NAME = "FIRE_TIME"; + private static final String SCHEDULED_FIRE_TIME_VARIABLE_NAME = "SCHEDULED_FIRE_TIME"; + + public static final FormatDateTimeFormatter dateTimeFormatter = DateFieldMapper.Defaults.DATE_TIME_FORMATTER; private AlertUtils() { } + /** + * Creates a new search request applying the scheduledFireTime and fireTime to the original request + */ + public static SearchRequest createSearchRequestWithTimes(SearchRequest request, DateTime scheduledFireTime, DateTime fireTime, ScriptService scriptService) throws IOException { + SearchRequest triggerSearchRequest = new SearchRequest(request) + .indicesOptions(request.indicesOptions()) + .indices(request.indices()); + if (Strings.hasLength(request.source())) { + Map templateParams = new HashMap<>(); + templateParams.put(SCHEDULED_FIRE_TIME_VARIABLE_NAME, dateTimeFormatter.printer().print(scheduledFireTime)); + templateParams.put(FIRE_TIME_VARIABLE_NAME, dateTimeFormatter.printer().print(fireTime)); + String requestSource = XContentHelper.convertToJson(request.source(), false); + ExecutableScript script = scriptService.executable("mustache", requestSource, ScriptService.ScriptType.INLINE, templateParams); + triggerSearchRequest.source((BytesReference) script.unwrap(script.run()), false); + } else if (request.templateName() != null) { + MapBuilder templateParams = MapBuilder.newMapBuilder(request.templateParams()) + .put(SCHEDULED_FIRE_TIME_VARIABLE_NAME, dateTimeFormatter.printer().print(scheduledFireTime)) + .put(FIRE_TIME_VARIABLE_NAME, dateTimeFormatter.printer().print(fireTime)); + triggerSearchRequest.templateParams(templateParams.map()); + triggerSearchRequest.templateName(request.templateName()); + triggerSearchRequest.templateType(request.templateType()); + } else { + throw new ElasticsearchIllegalStateException("Search requests needs either source or template name"); + } + return triggerSearchRequest; + } + + public static SearchRequest readSearchRequest(XContentParser parser) throws IOException { + return readSearchRequest(parser, DEFAULT_TRIGGER_SEARCH_TYPE); + } + /** * Reads a new search request instance for the specified parser. */ - public static SearchRequest readSearchRequest(XContentParser parser) throws IOException { + public static SearchRequest readSearchRequest(XContentParser parser, SearchType searchType) throws IOException { SearchRequest searchRequest = new SearchRequest(); IndicesOptions indicesOptions = DEFAULT_INDICES_OPTIONS; - SearchType searchType = DEFAULT_SEARCH_TYPE; XContentParser.Token token; String searchRequestFieldName = null; @@ -182,7 +223,7 @@ public final class AlertUtils { builder.field("allow_no_indices", options.allowNoIndices()); builder.endObject(); } - if (searchRequest.searchType() != DEFAULT_SEARCH_TYPE) { + if (searchRequest.searchType() != DEFAULT_TRIGGER_SEARCH_TYPE) { builder.field("search_type", searchRequest.searchType().toString().toLowerCase(Locale.ENGLISH)); } builder.endObject(); diff --git a/src/main/java/org/elasticsearch/alerts/AlertsStore.java b/src/main/java/org/elasticsearch/alerts/AlertsStore.java index 585fb3e9acd..6ad97c51050 100644 --- a/src/main/java/org/elasticsearch/alerts/AlertsStore.java +++ b/src/main/java/org/elasticsearch/alerts/AlertsStore.java @@ -52,7 +52,8 @@ public class AlertsStore extends AbstractComponent { public static final ParseField TRIGGER_FIELD = new ParseField("trigger"); public static final ParseField ACTION_FIELD = new ParseField("actions"); public static final ParseField LAST_ACTION_FIRE = new ParseField("last_alert_executed"); - public static final ParseField REQUEST_FIELD = new ParseField("request"); + public static final ParseField TRIGGER_REQUEST_FIELD = new ParseField("trigger_request"); + public static final ParseField PAYLOAD_REQUEST_FIELD = new ParseField("payload_request"); public static final ParseField THROTTLE_PERIOD_FIELD = new ParseField("throttle_period"); public static final ParseField LAST_ACTION_EXECUTED_FIELD = new ParseField("last_action_executed"); public static final ParseField ACK_STATE_FIELD = new ParseField("ack_state"); @@ -253,8 +254,10 @@ public class AlertsStore extends AbstractComponent { } else if (ACTION_FIELD.match(currentFieldName)) { List actions = alertActionRegistry.instantiateAlertActions(parser); alert.setActions(actions); - } else if (REQUEST_FIELD.match(currentFieldName)) { - alert.setSearchRequest(AlertUtils.readSearchRequest(parser)); + } else if (TRIGGER_REQUEST_FIELD.match(currentFieldName)) { + alert.setTriggerSearchRequest(AlertUtils.readSearchRequest(parser, AlertUtils.DEFAULT_TRIGGER_SEARCH_TYPE)); + } else if (PAYLOAD_REQUEST_FIELD.match(currentFieldName)) { + alert.setPayloadSearchRequest(AlertUtils.readSearchRequest(parser, AlertUtils.DEFAULT_PAYLOAD_SEARCH_TYPE)); } else if (META_FIELD.match(currentFieldName)) { alert.setMetadata(parser.map()); } else { diff --git a/src/main/java/org/elasticsearch/alerts/actions/AlertActionEntry.java b/src/main/java/org/elasticsearch/alerts/actions/AlertActionEntry.java index 5b1eb7e0bdb..9fc64d019e3 100644 --- a/src/main/java/org/elasticsearch/alerts/actions/AlertActionEntry.java +++ b/src/main/java/org/elasticsearch/alerts/actions/AlertActionEntry.java @@ -31,14 +31,14 @@ public class AlertActionEntry implements ToXContent { private AlertTrigger trigger; private List actions; private AlertActionState state; - private SearchRequest searchRequest; - /*Optional*/ - private Map searchResponse; + private SearchRequest triggerRequest; + + /*Optional*/ + private Map triggerResponse; private boolean triggered; private String errorMsg; private Map metadata; - private transient long version; private transient XContentType contentType; @@ -53,11 +53,10 @@ public class AlertActionEntry implements ToXContent { this.trigger = alert.getTrigger(); this.actions = alert.getActions(); this.state = state; - this.searchRequest = alert.getSearchRequest(); this.metadata = alert.getMetadata(); - this.version = 1; this.contentType = alert.getContentType(); + this.triggerRequest = alert.getTriggerSearchRequest(); } /** @@ -129,23 +128,23 @@ public class AlertActionEntry implements ToXContent { /** * @return The query that ran at fire time */ - public SearchRequest getSearchRequest() { - return searchRequest; + public SearchRequest getTriggerRequest() { + return triggerRequest; } - void setSearchRequest(SearchRequest searchRequest) { - this.searchRequest = searchRequest; + public void setTriggerRequest(SearchRequest triggerRequest) { + this.triggerRequest = triggerRequest; } /** * @return The search response that resulted at out the search request that ran. */ - public Map getSearchResponse() { - return searchResponse; + public Map getTriggerResponse() { + return triggerResponse; } - void setSearchResponse(Map searchResponse) { - this.searchResponse = searchResponse; + public void setTriggerResponse(Map triggerResponse) { + this.triggerResponse = triggerResponse; } /** @@ -223,9 +222,9 @@ public class AlertActionEntry implements ToXContent { historyEntry.field(trigger.getTriggerName(), trigger, params); historyEntry.endObject(); historyEntry.field("request"); - AlertUtils.writeSearchRequest(searchRequest, historyEntry, params); - if (searchResponse != null) { - historyEntry.field("response", searchResponse); + AlertUtils.writeSearchRequest(triggerRequest, historyEntry, params); + if (triggerResponse != null) { + historyEntry.field("response", triggerResponse); } historyEntry.startObject("actions"); diff --git a/src/main/java/org/elasticsearch/alerts/actions/AlertActionManager.java b/src/main/java/org/elasticsearch/alerts/actions/AlertActionManager.java index a4ce4dd9303..e1af7874428 100644 --- a/src/main/java/org/elasticsearch/alerts/actions/AlertActionManager.java +++ b/src/main/java/org/elasticsearch/alerts/actions/AlertActionManager.java @@ -223,10 +223,10 @@ public class AlertActionManager extends AbstractComponent { entry.setTrigger(triggerManager.instantiateAlertTrigger(parser)); break; case REQUEST: - entry.setSearchRequest(AlertUtils.readSearchRequest(parser)); + entry.setTriggerRequest(AlertUtils.readSearchRequest(parser)); break; case RESPONSE: - entry.setSearchResponse(parser.map()); + entry.setTriggerResponse(parser.map()); break; case METADATA: entry.setMetadata(parser.map()); @@ -355,7 +355,7 @@ public class AlertActionManager extends AbstractComponent { updateHistoryEntry(entry, AlertActionState.SEARCH_UNDERWAY); logger.debug("Running an alert action entry for [{}]", entry.getAlertName()); TriggerResult result = alertManager.executeAlert(entry); - entry.setSearchResponse(result.getResponse()); + entry.setTriggerResponse(result.getTriggerResponse()); if (result.isTriggered()) { entry.setTriggered(true); if (result.isThrottled()) { diff --git a/src/main/java/org/elasticsearch/alerts/actions/AlertActionRegistry.java b/src/main/java/org/elasticsearch/alerts/actions/AlertActionRegistry.java index da97a6f76aa..f190767de53 100644 --- a/src/main/java/org/elasticsearch/alerts/actions/AlertActionRegistry.java +++ b/src/main/java/org/elasticsearch/alerts/actions/AlertActionRegistry.java @@ -59,11 +59,11 @@ public class AlertActionRegistry extends AbstractComponent { return actions; } - public void doAction(Alert alert, TriggerResult actionEntry){ + public void doAction(Alert alert, TriggerResult triggerResult){ for (AlertAction action : alert.getActions()) { AlertActionFactory factory = actionImplemented.get(action.getActionName()); if (factory != null) { - factory.doAction(action, alert, actionEntry); + factory.doAction(action, alert, triggerResult); } else { throw new ElasticsearchIllegalArgumentException("No action exists with the name [" + action.getActionName() + "]"); } diff --git a/src/main/java/org/elasticsearch/alerts/actions/EmailAlertActionFactory.java b/src/main/java/org/elasticsearch/alerts/actions/EmailAlertActionFactory.java index 4391d3ccbb8..7eb0c9bee5b 100644 --- a/src/main/java/org/elasticsearch/alerts/actions/EmailAlertActionFactory.java +++ b/src/main/java/org/elasticsearch/alerts/actions/EmailAlertActionFactory.java @@ -92,12 +92,12 @@ public class EmailAlertActionFactory implements AlertActionFactory { message.setSubject("Elasticsearch Alert " + alert.getAlertName() + " triggered"); StringBuilder output = new StringBuilder(); output.append("The following query triggered because ").append(result.getTrigger().toString()).append("\n"); - Object totalHits = XContentMapValues.extractValue("hits.total", result.getResponse()); + Object totalHits = XContentMapValues.extractValue("hits.total", result.getTriggerResponse()); output.append("The total number of hits returned : ").append(totalHits).append("\n"); - output.append("For query : ").append(result.getRequest()); + output.append("For query : ").append(result.getActionRequest()); output.append("\n"); output.append("Indices : "); - for (String index : result.getRequest().indices()) { + for (String index : result.getActionRequest().indices()) { output.append(index); output.append("/"); } @@ -105,7 +105,7 @@ public class EmailAlertActionFactory implements AlertActionFactory { output.append("\n"); if (emailAlertAction.getDisplayField() != null) { - List> hits = (List>) XContentMapValues.extractValue("hits.hits", result.getResponse()); + List> hits = (List>) XContentMapValues.extractValue("hits.hits", result.getActionResponse()); for (Map hit : hits) { Map _source = (Map) hit.get("_source"); if (_source.containsKey(emailAlertAction.getDisplayField())) { @@ -116,7 +116,7 @@ public class EmailAlertActionFactory implements AlertActionFactory { output.append("\n"); } } else { - output.append(result.getResponse().toString()); + output.append(result.getActionResponse().toString()); } message.setText(output.toString()); diff --git a/src/main/java/org/elasticsearch/alerts/actions/IndexAlertActionFactory.java b/src/main/java/org/elasticsearch/alerts/actions/IndexAlertActionFactory.java index 9d12fd1d584..90d08270f3d 100644 --- a/src/main/java/org/elasticsearch/alerts/actions/IndexAlertActionFactory.java +++ b/src/main/java/org/elasticsearch/alerts/actions/IndexAlertActionFactory.java @@ -70,7 +70,7 @@ public class IndexAlertActionFactory implements AlertActionFactory { try { XContentBuilder resultBuilder = XContentFactory.jsonBuilder().prettyPrint(); resultBuilder.startObject(); - resultBuilder.field("response", result.getResponse()); + resultBuilder.field("response", result.getActionResponse()); resultBuilder.field("timestamp", alert.getLastExecuteTime()); ///@TODO FIXME the firetime should be in the result ? resultBuilder.endObject(); indexRequest.source(resultBuilder); diff --git a/src/main/java/org/elasticsearch/alerts/triggers/TriggerManager.java b/src/main/java/org/elasticsearch/alerts/triggers/TriggerManager.java index d6af66f25ee..b1a99b0845d 100644 --- a/src/main/java/org/elasticsearch/alerts/triggers/TriggerManager.java +++ b/src/main/java/org/elasticsearch/alerts/triggers/TriggerManager.java @@ -6,40 +6,29 @@ package org.elasticsearch.alerts.triggers; import org.elasticsearch.ElasticsearchIllegalArgumentException; -import org.elasticsearch.ElasticsearchIllegalStateException; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.alerts.Alert; +import org.elasticsearch.alerts.AlertUtils; import org.elasticsearch.client.Client; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.collect.ImmutableOpenMap; -import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.joda.FormatDateTimeFormatter; import org.elasticsearch.common.joda.time.DateTime; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.index.mapper.core.DateFieldMapper; -import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.ScriptService; import org.elasticsearch.search.SearchHit; import java.io.IOException; -import java.util.HashMap; import java.util.Map; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; public class TriggerManager extends AbstractComponent { - private static final String FIRE_TIME_VARIABLE_NAME = "FIRE_TIME"; - private static final String SCHEDULED_FIRE_TIME_VARIABLE_NAME = "SCHEDULED_FIRE_TIME"; - public static final FormatDateTimeFormatter dateTimeFormatter = DateFieldMapper.Defaults.DATE_TIME_FORMATTER; - private final Client client; private final ScriptService scriptService; private volatile ImmutableOpenMap triggersImplemented; @@ -101,7 +90,7 @@ public class TriggerManager extends AbstractComponent { * @throws IOException */ public TriggerResult isTriggered(Alert alert, DateTime scheduledFireTime, DateTime fireTime) throws IOException { - SearchRequest request = prepareTriggerSearch(alert, scheduledFireTime, fireTime); + SearchRequest request = AlertUtils.createSearchRequestWithTimes(alert.getTriggerSearchRequest(), scheduledFireTime, fireTime, scriptService); if (logger.isTraceEnabled()) { logger.trace("For alert [{}] running query for [{}]", alert.getAlertName(), XContentHelper.convertToJson(request.source(), false, true)); } @@ -129,28 +118,4 @@ public class TriggerManager extends AbstractComponent { return new TriggerResult(triggered, request, response, trigger); } - private SearchRequest prepareTriggerSearch(Alert alert, DateTime scheduledFireTime, DateTime fireTime) throws IOException { - SearchRequest triggerSearchRequest = new SearchRequest(alert.getSearchRequest()) - .indicesOptions(alert.getSearchRequest().indicesOptions()) - .indices(alert.getSearchRequest().indices()); - if (Strings.hasLength(alert.getSearchRequest().source())) { - Map templateParams = new HashMap<>(); - templateParams.put(SCHEDULED_FIRE_TIME_VARIABLE_NAME, dateTimeFormatter.printer().print(scheduledFireTime)); - templateParams.put(FIRE_TIME_VARIABLE_NAME, dateTimeFormatter.printer().print(fireTime)); - String requestSource = XContentHelper.convertToJson(alert.getSearchRequest().source(), false); - ExecutableScript script = scriptService.executable("mustache", requestSource, ScriptService.ScriptType.INLINE, templateParams); - triggerSearchRequest.source((BytesReference) script.unwrap(script.run()), false); - } else if (alert.getSearchRequest().templateName() != null) { - MapBuilder templateParams = MapBuilder.newMapBuilder(alert.getSearchRequest().templateParams()) - .put(SCHEDULED_FIRE_TIME_VARIABLE_NAME, dateTimeFormatter.printer().print(scheduledFireTime)) - .put(FIRE_TIME_VARIABLE_NAME, dateTimeFormatter.printer().print(fireTime)); - triggerSearchRequest.templateParams(templateParams.map()); - triggerSearchRequest.templateName(alert.getSearchRequest().templateName()); - triggerSearchRequest.templateType(alert.getSearchRequest().templateType()); - } else { - throw new ElasticsearchIllegalStateException("Search requests needs either source or template name"); - } - return triggerSearchRequest; - } - } diff --git a/src/main/java/org/elasticsearch/alerts/triggers/TriggerResult.java b/src/main/java/org/elasticsearch/alerts/triggers/TriggerResult.java index 3287ea96cf8..8cfa52a6549 100644 --- a/src/main/java/org/elasticsearch/alerts/triggers/TriggerResult.java +++ b/src/main/java/org/elasticsearch/alerts/triggers/TriggerResult.java @@ -15,14 +15,17 @@ public class TriggerResult { private final boolean triggered; private boolean throttled; - private final SearchRequest request; - private final Map response; + private final SearchRequest triggerRequest; + private final Map triggerResponse; private final AlertTrigger trigger; - public TriggerResult(boolean triggered, SearchRequest request, Map response, AlertTrigger trigger) { + private SearchRequest payloadRequest = null; + private Map payloadResponse = null; + + public TriggerResult(boolean triggered, SearchRequest triggerRequest, Map triggerResponse, AlertTrigger trigger) { this.triggered = triggered; - this.request = request; - this.response = response; + this.triggerRequest = triggerRequest; + this.triggerResponse = triggerResponse; this.trigger = trigger; } @@ -38,16 +41,61 @@ public class TriggerResult { this.throttled = throttled; } - public SearchRequest getRequest() { - return request; + /** + * Get's the request to trigger + */ + public SearchRequest getTriggerRequest() { + return triggerRequest; } - public Map getResponse() { - return response; + /** + * The response from the trigger request + * @return + */ + public Map getTriggerResponse() { + return triggerResponse; + } + + /** + * The request to generate the payloads for the alert actions + * @return + */ + public SearchRequest getPayloadRequest() { + return payloadRequest; + } + + public void setPayloadRequest(SearchRequest payloadRequest) { + this.payloadRequest = payloadRequest; + } + + /** + * The response from the payload request + * @return + */ + public Map getPayloadResponse() { + return payloadResponse; + } + + public void setPayloadResponse(Map payloadResponse) { + this.payloadResponse = payloadResponse; } public AlertTrigger getTrigger() { return trigger; } + /** + * @return the response the actions should use + */ + public Map getActionResponse() { + return payloadResponse != null ? payloadResponse : triggerResponse; + } + + /** + * @return the request the actions should use + */ + public SearchRequest getActionRequest() { + return payloadRequest != null ? payloadRequest : triggerRequest; + } + } diff --git a/src/main/resources/alerts.json b/src/main/resources/alerts.json index 2fb6b431b4d..3b0d932be53 100644 --- a/src/main/resources/alerts.json +++ b/src/main/resources/alerts.json @@ -38,7 +38,12 @@ "enabled" : false, "dynamic" : true }, - "request": { + "trigger_request": { + "type" : "object", + "enabled" : false, + "dynamic" : true + }, + "payload_request": { "type" : "object", "enabled" : false, "dynamic" : true diff --git a/src/test/java/org/elasticsearch/alerts/AbstractAlertingTests.java b/src/test/java/org/elasticsearch/alerts/AbstractAlertingTests.java index 27d30650dd1..ab91d051306 100644 --- a/src/test/java/org/elasticsearch/alerts/AbstractAlertingTests.java +++ b/src/test/java/org/elasticsearch/alerts/AbstractAlertingTests.java @@ -106,7 +106,7 @@ public abstract class AbstractAlertingTests extends ElasticsearchIntegrationTest } builder.startObject(); builder.field("schedule", cron); - builder.field("request"); + builder.field("trigger_request"); AlertUtils.writeSearchRequest(request, builder, ToXContent.EMPTY_PARAMS); if (metadata != null) { @@ -133,7 +133,7 @@ public abstract class AbstractAlertingTests extends ElasticsearchIntegrationTest protected SearchRequest createTriggerSearchRequest(String... indices) { SearchRequest request = new SearchRequest(indices); request.indicesOptions(AlertUtils.DEFAULT_INDICES_OPTIONS); - request.searchType(AlertUtils.DEFAULT_SEARCH_TYPE); + request.searchType(AlertUtils.DEFAULT_TRIGGER_SEARCH_TYPE); return request; } diff --git a/src/test/java/org/elasticsearch/alerts/AlertSerializationTest.java b/src/test/java/org/elasticsearch/alerts/AlertSerializationTest.java index 59b43ea745f..973819957d6 100644 --- a/src/test/java/org/elasticsearch/alerts/AlertSerializationTest.java +++ b/src/test/java/org/elasticsearch/alerts/AlertSerializationTest.java @@ -15,7 +15,6 @@ import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.script.ScriptService; -import org.elasticsearch.test.ElasticsearchIntegrationTest; import org.junit.Test; import java.util.ArrayList; @@ -23,17 +22,21 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -public class AlertSerializationTest extends ElasticsearchIntegrationTest { +import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; +import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource; + +public class AlertSerializationTest extends AbstractAlertingTests { @Test public void testAlertSerialization() throws Exception { - SearchRequest request = new SearchRequest(); - request.indices("my-index"); + SearchRequest triggerRequest = createTriggerSearchRequest("my-trigger-index").source(searchSource().query(matchAllQuery())); + SearchRequest payloadRequest = createTriggerSearchRequest("my-payload-index").source(searchSource().query(matchAllQuery())); + List actions = new ArrayList<>(); actions.add(new EmailAlertAction("message", "foo@bar.com")); Alert alert = new Alert("test-serialization", - request, + triggerRequest, new ScriptedTrigger("return true", ScriptService.ScriptType.INLINE, "groovy"), actions, "0/5 * * * * ? *", @@ -42,8 +45,9 @@ public class AlertSerializationTest extends ElasticsearchIntegrationTest { new TimeValue(0), AlertAckState.NOT_TRIGGERED); + alert.setPayloadSearchRequest(payloadRequest); Map metadata = new HashMap<>(); - metadata.put("foo","bar"); + metadata.put("foo", "bar"); metadata.put("list", "baz"); alert.setMetadata(metadata); @@ -51,14 +55,16 @@ public class AlertSerializationTest extends ElasticsearchIntegrationTest { alert.toXContent(jsonBuilder, ToXContent.EMPTY_PARAMS); final AlertsStore alertsStore = - internalCluster().getInstance(AlertsStore.class, internalCluster().getMasterName()); + internalTestCluster().getInstance(AlertsStore.class, internalTestCluster().getMasterName()); Alert parsedAlert = alertsStore.parseAlert("test-serialization", jsonBuilder.bytes()); + assertEquals(parsedAlert.getVersion(), alert.getVersion()); assertEquals(parsedAlert.getActions(), alert.getActions()); assertEquals(parsedAlert.getLastExecuteTime().getMillis(), alert.getLastExecuteTime().getMillis()); assertEquals(parsedAlert.getSchedule(), alert.getSchedule()); - assertEquals(parsedAlert.getSearchRequest().source(), alert.getSearchRequest().source()); + assertEquals(parsedAlert.getTriggerSearchRequest().indices()[0], "my-trigger-index"); + assertEquals(parsedAlert.getPayloadSearchRequest().indices()[0], "my-payload-index"); assertEquals(parsedAlert.getTrigger(), alert.getTrigger()); assertEquals(parsedAlert.getThrottlePeriod(), alert.getThrottlePeriod()); if (parsedAlert.getTimeLastActionExecuted() == null) { @@ -68,7 +74,4 @@ public class AlertSerializationTest extends ElasticsearchIntegrationTest { assertEquals(parsedAlert.getMetadata(), alert.getMetadata()); } - - - } diff --git a/src/test/java/org/elasticsearch/alerts/AlertThrottleTests.java b/src/test/java/org/elasticsearch/alerts/AlertThrottleTests.java index bb37a98d11b..1dc821f0927 100644 --- a/src/test/java/org/elasticsearch/alerts/AlertThrottleTests.java +++ b/src/test/java/org/elasticsearch/alerts/AlertThrottleTests.java @@ -52,11 +52,11 @@ public class AlertThrottleTests extends AbstractAlertingTests { Alert alert = new Alert(); alert.setAckState(AlertAckState.NOT_TRIGGERED); - alert.setSearchRequest(createTriggerSearchRequest("test-index").source(searchSource().query(matchAllQuery()))); + + alert.setTriggerSearchRequest(createTriggerSearchRequest("test-index").source(searchSource().query(matchAllQuery()))); alert.setTrigger(new ScriptedTrigger("hits.total > 0", ScriptService.ScriptType.INLINE, "groovy")); alert.getActions().add(new IndexAlertAction("action-index", "action-type")); alert.setSchedule("0/5 * * * * ? *"); - alert.lastExecuteTime(new DateTime()); XContentBuilder jsonBuilder = XContentFactory.jsonBuilder(); alert.toXContent(jsonBuilder, ToXContent.EMPTY_PARAMS); @@ -124,10 +124,11 @@ public class AlertThrottleTests extends AbstractAlertingTests { Alert alert = new Alert(); alert.setAckState(AlertAckState.NOT_ACKABLE); - alert.setSearchRequest(createTriggerSearchRequest("test-index").source(searchSource().query(matchAllQuery()))); + alert.setTriggerSearchRequest(createTriggerSearchRequest("test-index").source(searchSource().query(matchAllQuery()))); alert.setTrigger(new ScriptedTrigger("hits.total > 0", ScriptService.ScriptType.INLINE, "groovy")); alert.getActions().add(new IndexAlertAction("action-index", "action-type")); alert.setSchedule("0/5 * * * * ? *"); + alert.lastExecuteTime(new DateTime()); alert.setThrottlePeriod(new TimeValue(10, TimeUnit.SECONDS)); diff --git a/src/test/java/org/elasticsearch/alerts/PayloadSearchTest.java b/src/test/java/org/elasticsearch/alerts/PayloadSearchTest.java new file mode 100644 index 00000000000..4610cb9f65f --- /dev/null +++ b/src/test/java/org/elasticsearch/alerts/PayloadSearchTest.java @@ -0,0 +1,75 @@ +/* + * 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.alerts; + +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.alerts.actions.AlertAction; +import org.elasticsearch.alerts.actions.IndexAlertAction; +import org.elasticsearch.alerts.transport.actions.put.PutAlertResponse; +import org.elasticsearch.alerts.triggers.ScriptedTrigger; +import org.elasticsearch.common.joda.time.DateTime; +import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.script.ScriptService; +import org.elasticsearch.search.SearchHit; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; +import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource; +import static org.hamcrest.Matchers.greaterThan; + +/** + */ +public class PayloadSearchTest extends AbstractAlertingTests { + + @Test + public void testPayloadSearchRequest() throws Exception { + createIndex("my-trigger-index", "my-payload-index", "my-payload-output"); + ensureGreen("my-trigger-index", "my-payload-index", "my-payload-output"); + + index("my-payload-index","payload", "mytestresult"); + refresh(); + + SearchRequest triggerRequest = createTriggerSearchRequest("my-trigger-index").source(searchSource().query(matchAllQuery())); + SearchRequest payloadRequest = createTriggerSearchRequest("my-payload-index").source(searchSource().query(matchAllQuery())); + payloadRequest.searchType(AlertUtils.DEFAULT_PAYLOAD_SEARCH_TYPE); + + List actions = new ArrayList<>(); + actions.add(new IndexAlertAction("my-payload-output","result")); + Alert alert = new Alert("test-payload", + triggerRequest, + new ScriptedTrigger("return true", ScriptService.ScriptType.INLINE, "groovy"), + actions, + "0/5 * * * * ? *", + new DateTime(), + 0, + new TimeValue(0), + AlertAckState.NOT_ACKABLE); + + alert.setPayloadSearchRequest(payloadRequest); + XContentBuilder jsonBuilder = XContentFactory.jsonBuilder(); + alert.toXContent(jsonBuilder, ToXContent.EMPTY_PARAMS); + PutAlertResponse putAlertResponse = alertClient().preparePutAlert("test-payload").setAlertSource(jsonBuilder.bytes()).get(); + assertTrue(putAlertResponse.indexResponse().isCreated()); + + assertAlertTriggered("test-payload", 1, false); + refresh(); + SearchRequest searchRequest = client().prepareSearch("my-payload-output").request(); + searchRequest.source(searchSource().query(matchAllQuery())); + SearchResponse searchResponse = client().search(searchRequest).actionGet(); + assertThat(searchResponse.getHits().getTotalHits(), greaterThan(0L)); + SearchHit hit = searchResponse.getHits().getHits()[0]; + String source = hit.getSourceRef().toUtf8(); + + assertTrue(source.contains("mytestresult")); + } +} diff --git a/src/test/java/org/elasticsearch/alerts/actions/AlertActionsTest.java b/src/test/java/org/elasticsearch/alerts/actions/AlertActionsTest.java index 02745adc080..3f2238d24ad 100644 --- a/src/test/java/org/elasticsearch/alerts/actions/AlertActionsTest.java +++ b/src/test/java/org/elasticsearch/alerts/actions/AlertActionsTest.java @@ -19,7 +19,6 @@ import org.elasticsearch.alerts.transport.actions.put.PutAlertRequest; import org.elasticsearch.alerts.transport.actions.put.PutAlertResponse; import org.elasticsearch.alerts.triggers.AlertTrigger; import org.elasticsearch.alerts.triggers.ScriptedTrigger; -import org.elasticsearch.alerts.triggers.TriggerManager; import org.elasticsearch.alerts.triggers.TriggerResult; import org.elasticsearch.common.joda.time.DateTime; import org.elasticsearch.common.joda.time.DateTimeZone; @@ -70,8 +69,8 @@ public class AlertActionsTest extends AbstractAlertingTests { builder.startObject(); builder.field(AlertActionManager.ALERT_NAME_FIELD, "testName"); builder.field(AlertActionManager.TRIGGERED_FIELD, true); - builder.field(AlertActionManager.FIRE_TIME_FIELD, TriggerManager.dateTimeFormatter.printer().print(fireTime)); - builder.field(AlertActionManager.SCHEDULED_FIRE_TIME_FIELD, TriggerManager.dateTimeFormatter.printer().print(scheduledFireTime)); + builder.field(AlertActionManager.FIRE_TIME_FIELD, AlertUtils.dateTimeFormatter.printer().print(fireTime)); + builder.field(AlertActionManager.SCHEDULED_FIRE_TIME_FIELD, AlertUtils.dateTimeFormatter.printer().print(scheduledFireTime)); builder.field(AlertActionManager.TRIGGER_FIELD, triggerMap); SearchRequest searchRequest = new SearchRequest("test123"); builder.field(AlertActionManager.REQUEST); @@ -96,7 +95,7 @@ public class AlertActionsTest extends AbstractAlertingTests { assertEquals(actionEntry.getScheduledTime(), scheduledFireTime); assertEquals(actionEntry.getFireTime(), fireTime); assertEquals(actionEntry.getState(), AlertActionState.SEARCH_NEEDED); - assertEquals(XContentMapValues.extractValue("hits.total", actionEntry.getSearchResponse()), 10); + assertEquals(XContentMapValues.extractValue("hits.total", actionEntry.getTriggerResponse()), 10); } @Test From 14ca6ec300fa44e454dfbca4ed2c98a13624adaa Mon Sep 17 00:00:00 2001 From: Brian Murphy Date: Fri, 28 Nov 2014 10:30:23 +0000 Subject: [PATCH 2/2] Add payload search and response to AlertActionEntry. Original commit: elastic/x-pack-elasticsearch@b88b63e8a93a60609c0da08c389b5f915aff18d2 --- .../alerts/actions/AlertActionEntry.java | 38 ++++++++++++++++++- .../alerts/actions/AlertActionManager.java | 18 +++++++-- src/main/resources/alerthistory.json | 14 ++++++- .../alerts/actions/AlertActionsTest.java | 4 +- 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/elasticsearch/alerts/actions/AlertActionEntry.java b/src/main/java/org/elasticsearch/alerts/actions/AlertActionEntry.java index 9fc64d019e3..ac148b8290e 100644 --- a/src/main/java/org/elasticsearch/alerts/actions/AlertActionEntry.java +++ b/src/main/java/org/elasticsearch/alerts/actions/AlertActionEntry.java @@ -36,6 +36,8 @@ public class AlertActionEntry implements ToXContent { /*Optional*/ private Map triggerResponse; + private SearchRequest payloadRequest; + private Map payloadResponse; private boolean triggered; private String errorMsg; private Map metadata; @@ -210,6 +212,30 @@ public class AlertActionEntry implements ToXContent { this.metadata = metadata; } + /** + * @return the payload search response + */ + public Map getPayloadResponse() { + return payloadResponse; + } + + public void setPayloadResponse(Map payloadResponse) { + this.payloadResponse = payloadResponse; + } + + /** + * @return the payload search request + */ + public SearchRequest getPayloadRequest() { + return payloadRequest; + } + + public void setPayloadRequest(SearchRequest payloadRequest) { + this.payloadRequest = payloadRequest; + } + + + @Override public XContentBuilder toXContent(XContentBuilder historyEntry, Params params) throws IOException { historyEntry.startObject(); @@ -221,10 +247,18 @@ public class AlertActionEntry implements ToXContent { historyEntry.startObject(); historyEntry.field(trigger.getTriggerName(), trigger, params); historyEntry.endObject(); - historyEntry.field("request"); + historyEntry.field("trigger_request"); AlertUtils.writeSearchRequest(triggerRequest, historyEntry, params); if (triggerResponse != null) { - historyEntry.field("response", triggerResponse); + historyEntry.field("trigger_response", triggerResponse); + } + + if (payloadRequest != null) { + historyEntry.field("payload_request"); + AlertUtils.writeSearchRequest(payloadRequest, historyEntry, params); + } + if (payloadResponse != null) { + historyEntry.field("payload_response", triggerResponse); } historyEntry.startObject("actions"); diff --git a/src/main/java/org/elasticsearch/alerts/actions/AlertActionManager.java b/src/main/java/org/elasticsearch/alerts/actions/AlertActionManager.java index e1af7874428..e6b06b6ec04 100644 --- a/src/main/java/org/elasticsearch/alerts/actions/AlertActionManager.java +++ b/src/main/java/org/elasticsearch/alerts/actions/AlertActionManager.java @@ -54,8 +54,10 @@ public class AlertActionManager extends AbstractComponent { public static final String SCHEDULED_FIRE_TIME_FIELD = "scheduled_fire_time"; public static final String ERROR_MESSAGE = "error_msg"; public static final String TRIGGER_FIELD = "trigger"; - public static final String REQUEST = "request"; - public static final String RESPONSE = "response"; + public static final String TRIGGER_REQUEST = "trigger_request"; + public static final String TRIGGER_RESPONSE = "trigger_response"; + public static final String PAYLOAD_REQUEST = "payload_request"; + public static final String PAYLOAD_RESPONSE = "payload_response"; public static final String ACTIONS_FIELD = "actions"; public static final String STATE = "state"; public static final String METADATA = "meta"; @@ -222,12 +224,18 @@ public class AlertActionManager extends AbstractComponent { case TRIGGER_FIELD: entry.setTrigger(triggerManager.instantiateAlertTrigger(parser)); break; - case REQUEST: + case TRIGGER_REQUEST: entry.setTriggerRequest(AlertUtils.readSearchRequest(parser)); break; - case RESPONSE: + case TRIGGER_RESPONSE: entry.setTriggerResponse(parser.map()); break; + case PAYLOAD_REQUEST: + entry.setPayloadRequest(AlertUtils.readSearchRequest(parser)); + break; + case PAYLOAD_RESPONSE: + entry.setPayloadResponse(parser.map()); + break; case METADATA: entry.setMetadata(parser.map()); default: @@ -365,6 +373,8 @@ public class AlertActionManager extends AbstractComponent { } else if (entry.getState() != AlertActionState.THROTTLED) { entry.setState(AlertActionState.ACTION_PERFORMED); } + entry.setPayloadRequest(trigger.getPayloadRequest()); + entry.setPayloadResponse(trigger.getPayloadResponse()); } else { entry.setState(AlertActionState.NO_ACTION_NEEDED); } diff --git a/src/main/resources/alerthistory.json b/src/main/resources/alerthistory.json index 0aa7546ee8b..bbe93c02c9f 100644 --- a/src/main/resources/alerthistory.json +++ b/src/main/resources/alerthistory.json @@ -30,12 +30,22 @@ "error_msg": { "type": "string" }, - "request" : { + "trigger_request" : { "type" : "object", "enabled" : false, "dynamic" : true }, - "response" : { + "trigger_response" : { + "type" : "object", + "enabled" : false, + "dynamic" : true + }, + "payload_request" : { + "type" : "object", + "enabled" : false, + "dynamic" : true + }, + "payload_response" : { "type" : "object", "enabled" : false, "dynamic" : true diff --git a/src/test/java/org/elasticsearch/alerts/actions/AlertActionsTest.java b/src/test/java/org/elasticsearch/alerts/actions/AlertActionsTest.java index 3f2238d24ad..7ea599b3ef9 100644 --- a/src/test/java/org/elasticsearch/alerts/actions/AlertActionsTest.java +++ b/src/test/java/org/elasticsearch/alerts/actions/AlertActionsTest.java @@ -73,13 +73,13 @@ public class AlertActionsTest extends AbstractAlertingTests { builder.field(AlertActionManager.SCHEDULED_FIRE_TIME_FIELD, AlertUtils.dateTimeFormatter.printer().print(scheduledFireTime)); builder.field(AlertActionManager.TRIGGER_FIELD, triggerMap); SearchRequest searchRequest = new SearchRequest("test123"); - builder.field(AlertActionManager.REQUEST); + builder.field(AlertActionManager.TRIGGER_REQUEST); AlertUtils.writeSearchRequest(searchRequest, builder, ToXContent.EMPTY_PARAMS); SearchResponse searchResponse = new SearchResponse( new InternalSearchResponse(new InternalSearchHits(new InternalSearchHit[0], 10, 0), null, null, null, false, false), null, 1, 1, 0, new ShardSearchFailure[0] ); - builder.startObject(AlertActionManager.RESPONSE); + builder.startObject(AlertActionManager.TRIGGER_RESPONSE); builder.value(searchResponse); builder.endObject(); builder.field(AlertActionManager.ACTIONS_FIELD, actionMap);