Change project name to elasticsearch-watcher
- `alerts` package is now `watcher` package - we no longer use the term `Alert`, but instead we use `Watch` - documentation still needs to be updated Original commit: elastic/x-pack-elasticsearch@1225edf7e3
This commit is contained in:
parent
a6bdbf0b0b
commit
41832b6f5b
2
pom.xml
2
pom.xml
|
@ -6,7 +6,7 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>org.elasticsearch</groupId>
|
<groupId>org.elasticsearch</groupId>
|
||||||
<artifactId>elasticsearch-alerts</artifactId>
|
<artifactId>elasticsearch-watcher</artifactId>
|
||||||
<version>1.0.0-beta2-SNAPSHOT</version>
|
<version>1.0.0-beta2-SNAPSHOT</version>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
|
|
@ -1,57 +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.alerts;
|
|
||||||
|
|
||||||
|
|
||||||
import org.elasticsearch.alerts.actions.ActionModule;
|
|
||||||
import org.elasticsearch.alerts.client.AlertsClientModule;
|
|
||||||
import org.elasticsearch.alerts.condition.ConditionModule;
|
|
||||||
import org.elasticsearch.alerts.history.HistoryModule;
|
|
||||||
import org.elasticsearch.alerts.input.InputModule;
|
|
||||||
import org.elasticsearch.alerts.rest.AlertsRestModule;
|
|
||||||
import org.elasticsearch.alerts.scheduler.SchedulerModule;
|
|
||||||
import org.elasticsearch.alerts.support.TemplateUtils;
|
|
||||||
import org.elasticsearch.alerts.support.clock.ClockModule;
|
|
||||||
import org.elasticsearch.alerts.support.init.InitializingModule;
|
|
||||||
import org.elasticsearch.alerts.support.template.TemplateModule;
|
|
||||||
import org.elasticsearch.alerts.transform.TransformModule;
|
|
||||||
import org.elasticsearch.alerts.transport.AlertsTransportModule;
|
|
||||||
import org.elasticsearch.common.collect.ImmutableList;
|
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
|
||||||
import org.elasticsearch.common.inject.Module;
|
|
||||||
import org.elasticsearch.common.inject.SpawnModules;
|
|
||||||
|
|
||||||
|
|
||||||
public class AlertsModule extends AbstractModule implements SpawnModules {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<? extends Module> spawnModules() {
|
|
||||||
return ImmutableList.of(
|
|
||||||
new InitializingModule(),
|
|
||||||
new TemplateModule(),
|
|
||||||
new ClockModule(),
|
|
||||||
new AlertsClientModule(),
|
|
||||||
new TransformModule(),
|
|
||||||
new AlertsRestModule(),
|
|
||||||
new SchedulerModule(),
|
|
||||||
new AlertsTransportModule(),
|
|
||||||
new ConditionModule(),
|
|
||||||
new InputModule(),
|
|
||||||
new ActionModule(),
|
|
||||||
new HistoryModule());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure() {
|
|
||||||
bind(Alert.Parser.class).asEagerSingleton();
|
|
||||||
bind(AlertLockService.class).asEagerSingleton();
|
|
||||||
bind(AlertsLifeCycleService.class).asEagerSingleton();
|
|
||||||
bind(AlertsService.class).asEagerSingleton();
|
|
||||||
bind(AlertsStore.class).asEagerSingleton();
|
|
||||||
bind(TemplateUtils.class).asEagerSingleton();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,253 +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.alerts.client;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionFuture;
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.ack.AckAlertAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.ack.AckAlertRequest;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.ack.AckAlertRequestBuilder;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.ack.AckAlertResponse;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.delete.DeleteAlertAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.delete.DeleteAlertRequest;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.delete.DeleteAlertRequestBuilder;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.delete.DeleteAlertResponse;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.get.GetAlertAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.get.GetAlertRequest;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.get.GetAlertRequestBuilder;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.get.GetAlertResponse;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.put.PutAlertAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.put.PutAlertRequest;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.put.PutAlertRequestBuilder;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.put.PutAlertResponse;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.service.AlertsServiceAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.service.AlertsServiceRequest;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.service.AlertsServiceRequestBuilder;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.service.AlertsServiceResponse;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.stats.AlertsStatsAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.stats.AlertsStatsRequest;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.stats.AlertsStatsRequestBuilder;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.stats.AlertsStatsResponse;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
public class AlertsClient {
|
|
||||||
|
|
||||||
private final Client client;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public AlertsClient(Client client) {
|
|
||||||
this.client = client;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a request builder that gets an alert by name (id)
|
|
||||||
*
|
|
||||||
* @param alertName the name (id) of the alert
|
|
||||||
* @return The request builder
|
|
||||||
*/
|
|
||||||
public GetAlertRequestBuilder prepareGetAlert(String alertName) {
|
|
||||||
return new GetAlertRequestBuilder(client, alertName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a request builder that gets an alert
|
|
||||||
*
|
|
||||||
* @return the request builder
|
|
||||||
*/
|
|
||||||
public GetAlertRequestBuilder prepareGetAlert() {
|
|
||||||
return new GetAlertRequestBuilder(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets an alert from the alert index
|
|
||||||
*
|
|
||||||
* @param request The get alert request
|
|
||||||
* @param listener The listener for the get alert response containing the GetResponse for this alert
|
|
||||||
*/
|
|
||||||
public void getAlert(GetAlertRequest request, ActionListener<GetAlertResponse> listener) {
|
|
||||||
client.execute(GetAlertAction.INSTANCE, request, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets an alert from the alert index
|
|
||||||
*
|
|
||||||
* @param request The get alert request with the alert name (id)
|
|
||||||
* @return The response containing the GetResponse for this alert
|
|
||||||
*/
|
|
||||||
public ActionFuture<GetAlertResponse> getAlert(GetAlertRequest request) {
|
|
||||||
return client.execute(GetAlertAction.INSTANCE, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a request builder to delete an alert by name (id)
|
|
||||||
*
|
|
||||||
* @param alertName the name (id) of the alert
|
|
||||||
* @return The request builder
|
|
||||||
*/
|
|
||||||
public DeleteAlertRequestBuilder prepareDeleteAlert(String alertName) {
|
|
||||||
return new DeleteAlertRequestBuilder(client, alertName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a request builder that deletes an alert
|
|
||||||
*
|
|
||||||
* @return The request builder
|
|
||||||
*/
|
|
||||||
public DeleteAlertRequestBuilder prepareDeleteAlert() {
|
|
||||||
return new DeleteAlertRequestBuilder(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes an alert
|
|
||||||
*
|
|
||||||
* @param request The delete request with the alert name (id) to be deleted
|
|
||||||
* @param listener The listener for the delete alert response containing the DeleteResponse for this action
|
|
||||||
*/
|
|
||||||
public void deleteAlert(DeleteAlertRequest request, ActionListener<DeleteAlertResponse> listener) {
|
|
||||||
client.execute(DeleteAlertAction.INSTANCE, request, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes an alert
|
|
||||||
*
|
|
||||||
* @param request The delete request with the alert name (id) to be deleted
|
|
||||||
* @return The response containing the DeleteResponse for this action
|
|
||||||
*/
|
|
||||||
public ActionFuture<DeleteAlertResponse> deleteAlert(DeleteAlertRequest request) {
|
|
||||||
return client.execute(DeleteAlertAction.INSTANCE, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a request builder to build a request to put an alert
|
|
||||||
*
|
|
||||||
* @param alertName The name of the alert to put
|
|
||||||
* @return The builder to create the alert
|
|
||||||
*/
|
|
||||||
public PutAlertRequestBuilder preparePutAlert(String alertName) {
|
|
||||||
return new PutAlertRequestBuilder(client, alertName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a request builder to build a request to put an alert
|
|
||||||
*
|
|
||||||
* @return The builder
|
|
||||||
*/
|
|
||||||
public PutAlertRequestBuilder preparePutAlert() {
|
|
||||||
return new PutAlertRequestBuilder(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Put an alert and registers it with the scheduler
|
|
||||||
*
|
|
||||||
* @param request The request containing the alert to index and register
|
|
||||||
* @param listener The listener for the response containing the IndexResponse for this alert
|
|
||||||
*/
|
|
||||||
public void putAlert(PutAlertRequest request, ActionListener<PutAlertResponse> listener) {
|
|
||||||
client.execute(PutAlertAction.INSTANCE, request, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Put an alert and registers it with the scheduler
|
|
||||||
*
|
|
||||||
* @param request The request containing the alert to index and register
|
|
||||||
* @return The response containing the IndexResponse for this alert
|
|
||||||
*/
|
|
||||||
public ActionFuture<PutAlertResponse> putAlert(PutAlertRequest request) {
|
|
||||||
return client.execute(PutAlertAction.INSTANCE, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the alert stats
|
|
||||||
*
|
|
||||||
* @param request The request for the alert stats
|
|
||||||
* @return The response containing the StatsResponse for this action
|
|
||||||
*/
|
|
||||||
public ActionFuture<AlertsStatsResponse> alertsStats(AlertsStatsRequest request) {
|
|
||||||
return client.execute(AlertsStatsAction.INSTANCE, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a request builder to build a request to get the alerts stats
|
|
||||||
*
|
|
||||||
* @return The builder get the alerts stats
|
|
||||||
*/
|
|
||||||
public AlertsStatsRequestBuilder prepareAlertsStats() {
|
|
||||||
return new AlertsStatsRequestBuilder(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the alert stats
|
|
||||||
*
|
|
||||||
* @param request The request for the alert stats
|
|
||||||
* @param listener The listener for the response containing the AlertsStatsResponse
|
|
||||||
*/
|
|
||||||
public void alertsStats(AlertsStatsRequest request, ActionListener<AlertsStatsResponse> listener) {
|
|
||||||
client.execute(AlertsStatsAction.INSTANCE, request, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a request builder to ack an alert by name (id)
|
|
||||||
*
|
|
||||||
* @param alertName the name (id) of the alert
|
|
||||||
* @return The request builder
|
|
||||||
*/
|
|
||||||
public AckAlertRequestBuilder prepareAckAlert(String alertName) {
|
|
||||||
return new AckAlertRequestBuilder(client, alertName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a request builder that acks an alert
|
|
||||||
*
|
|
||||||
* @return The request builder
|
|
||||||
*/
|
|
||||||
public AckAlertRequestBuilder prepareAckAlert() {
|
|
||||||
return new AckAlertRequestBuilder(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ack an alert
|
|
||||||
*
|
|
||||||
* @param request The ack request with the alert name (id) to be acked
|
|
||||||
* @param listener The listener for the ack alert response
|
|
||||||
*/
|
|
||||||
public void ackAlert(AckAlertRequest request, ActionListener<AckAlertResponse> listener) {
|
|
||||||
client.execute(AckAlertAction.INSTANCE, request, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Acks an alert
|
|
||||||
*
|
|
||||||
* @param request The ack request with the alert name (id) to be acked
|
|
||||||
* @return The AckAlertResponse
|
|
||||||
*/
|
|
||||||
public ActionFuture<AckAlertResponse> ackAlert(AckAlertRequest request) {
|
|
||||||
return client.execute(AckAlertAction.INSTANCE, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare make an alert service request.
|
|
||||||
*/
|
|
||||||
public AlertsServiceRequestBuilder prepareAlertService() {
|
|
||||||
return new AlertsServiceRequestBuilder(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform an alert service request to either start, stop or restart the alerting plugin.
|
|
||||||
*/
|
|
||||||
public void alertService(AlertsServiceRequest request, ActionListener<AlertsServiceResponse> listener) {
|
|
||||||
client.execute(AlertsServiceAction.INSTANCE, request, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform an alert service request to either start, stop or restart the alerting plugin.
|
|
||||||
*/
|
|
||||||
public ActionFuture<AlertsServiceResponse> alertService(AlertsServiceRequest request) {
|
|
||||||
return client.execute(AlertsServiceAction.INSTANCE, request);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,189 +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.alerts.history;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
|
|
||||||
import org.elasticsearch.action.admin.indices.refresh.RefreshResponse;
|
|
||||||
import org.elasticsearch.action.index.IndexRequest;
|
|
||||||
import org.elasticsearch.action.index.IndexResponse;
|
|
||||||
import org.elasticsearch.action.search.*;
|
|
||||||
import org.elasticsearch.action.support.IndicesOptions;
|
|
||||||
import org.elasticsearch.alerts.support.TemplateUtils;
|
|
||||||
import org.elasticsearch.alerts.support.init.proxy.ClientProxy;
|
|
||||||
import org.elasticsearch.cluster.ClusterState;
|
|
||||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.joda.time.DateTime;
|
|
||||||
import org.elasticsearch.common.joda.time.format.DateTimeFormat;
|
|
||||||
import org.elasticsearch.common.joda.time.format.DateTimeFormatter;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
|
||||||
import org.elasticsearch.index.query.QueryBuilders;
|
|
||||||
import org.elasticsearch.search.SearchHit;
|
|
||||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
public class HistoryStore extends AbstractComponent {
|
|
||||||
|
|
||||||
public static final String ALERT_HISTORY_INDEX_PREFIX = ".alert_history_";
|
|
||||||
public static final String ALERT_HISTORY_TYPE = "fired_alert";
|
|
||||||
|
|
||||||
static final DateTimeFormatter alertHistoryIndexTimeFormat = DateTimeFormat.forPattern("YYYY-MM-dd");
|
|
||||||
|
|
||||||
private final ClientProxy client;
|
|
||||||
private final TemplateUtils templateUtils;
|
|
||||||
private final int scrollSize;
|
|
||||||
private final TimeValue scrollTimeout;
|
|
||||||
private final FiredAlert.Parser alertRecordParser;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public HistoryStore(Settings settings, ClientProxy client, TemplateUtils templateUtils, FiredAlert.Parser alertRecordParser) {
|
|
||||||
super(settings);
|
|
||||||
this.client = client;
|
|
||||||
this.templateUtils = templateUtils;
|
|
||||||
this.alertRecordParser = alertRecordParser;
|
|
||||||
this.scrollTimeout = settings.getAsTime("alerts.scroll.timeout", TimeValue.timeValueSeconds(30));
|
|
||||||
this.scrollSize = settings.getAsInt("alerts.scroll.size", 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void put(FiredAlert firedAlert) throws HistoryException {
|
|
||||||
String alertHistoryIndex = getAlertHistoryIndexNameForTime(firedAlert.scheduledTime());
|
|
||||||
try {
|
|
||||||
IndexResponse response = client.prepareIndex(alertHistoryIndex, ALERT_HISTORY_TYPE, firedAlert.id())
|
|
||||||
.setSource(XContentFactory.jsonBuilder().value(firedAlert))
|
|
||||||
.setOpType(IndexRequest.OpType.CREATE)
|
|
||||||
.get();
|
|
||||||
firedAlert.version(response.getVersion());
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new HistoryException("persisting new fired alert [" + firedAlert + "] failed", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(FiredAlert firedAlert) throws HistoryException {
|
|
||||||
logger.debug("updating fired alert [{}]", firedAlert);
|
|
||||||
try {
|
|
||||||
BytesReference bytes = XContentFactory.jsonBuilder().value(firedAlert).bytes();
|
|
||||||
IndexResponse response = client.prepareIndex(getAlertHistoryIndexNameForTime(firedAlert.scheduledTime()), ALERT_HISTORY_TYPE, firedAlert.id())
|
|
||||||
.setSource(bytes)
|
|
||||||
.setVersion(firedAlert.version())
|
|
||||||
.get();
|
|
||||||
firedAlert.version(response.getVersion());
|
|
||||||
logger.debug("updated fired alert [{}]", firedAlert);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new HistoryException("persisting fired alert [" + firedAlert + "] failed", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public LoadResult loadFiredAlerts(ClusterState state, FiredAlert.State firedAlertState) {
|
|
||||||
String[] indices = state.metaData().concreteIndices(IndicesOptions.lenientExpandOpen(), ALERT_HISTORY_INDEX_PREFIX + "*");
|
|
||||||
if (indices.length == 0) {
|
|
||||||
logger.debug("No .alert_history indices found, skip loading of alert actions");
|
|
||||||
templateUtils.ensureIndexTemplateIsLoaded(state, "alerthistory");
|
|
||||||
return new LoadResult(true);
|
|
||||||
}
|
|
||||||
int numPrimaryShards = 0;
|
|
||||||
for (String index : indices) {
|
|
||||||
IndexMetaData indexMetaData = state.getMetaData().index(index);
|
|
||||||
if (indexMetaData != null) {
|
|
||||||
if (!state.routingTable().index(index).allPrimaryShardsActive()) {
|
|
||||||
logger.debug("Not all primary shards of the [{}] index are started. Schedule to retry alert action loading..", index);
|
|
||||||
return new LoadResult(false);
|
|
||||||
} else {
|
|
||||||
numPrimaryShards += indexMetaData.numberOfShards();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RefreshResponse refreshResponse = client.refresh(new RefreshRequest(ALERT_HISTORY_INDEX_PREFIX + "*"));
|
|
||||||
if (refreshResponse.getSuccessfulShards() < numPrimaryShards) {
|
|
||||||
return new LoadResult(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchRequest searchRequest = createScanSearchRequest(firedAlertState);
|
|
||||||
SearchResponse response = client.search(searchRequest);
|
|
||||||
List<FiredAlert> alerts = new ArrayList<>();
|
|
||||||
try {
|
|
||||||
if (response.getTotalShards() != response.getSuccessfulShards()) {
|
|
||||||
return new LoadResult(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.getHits().getTotalHits() > 0) {
|
|
||||||
response = client.searchScroll(response.getScrollId(), scrollTimeout);
|
|
||||||
while (response.getHits().hits().length != 0) {
|
|
||||||
for (SearchHit sh : response.getHits()) {
|
|
||||||
String historyId = sh.getId();
|
|
||||||
FiredAlert historyEntry = alertRecordParser.parse(sh.getSourceRef(), historyId, sh.version());
|
|
||||||
assert historyEntry.state() == FiredAlert.State.AWAITS_EXECUTION;
|
|
||||||
logger.debug("loaded fired alert from index [{}/{}/{}]", sh.index(), sh.type(), sh.id());
|
|
||||||
alerts.add(historyEntry);
|
|
||||||
}
|
|
||||||
response = client.searchScroll(response.getScrollId(), scrollTimeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
client.clearScroll(response.getScrollId());
|
|
||||||
}
|
|
||||||
templateUtils.ensureIndexTemplateIsLoaded(state, "alerthistory");
|
|
||||||
return new LoadResult(true, alerts);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the correct alert history index name for a given time using alertHistoryIndexTimeFormat
|
|
||||||
*/
|
|
||||||
public static String getAlertHistoryIndexNameForTime(DateTime time) {
|
|
||||||
return ALERT_HISTORY_INDEX_PREFIX + alertHistoryIndexTimeFormat.print(time);
|
|
||||||
}
|
|
||||||
|
|
||||||
private SearchRequest createScanSearchRequest(FiredAlert.State firedAlertState) {
|
|
||||||
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
|
|
||||||
.query(QueryBuilders.termQuery(FiredAlert.Parser.STATE_FIELD.getPreferredName(), firedAlertState.id()))
|
|
||||||
.size(scrollSize)
|
|
||||||
.version(true);
|
|
||||||
|
|
||||||
SearchRequest searchRequest = new SearchRequest(ALERT_HISTORY_INDEX_PREFIX + "*");
|
|
||||||
searchRequest.source(sourceBuilder);
|
|
||||||
searchRequest.searchType(SearchType.SCAN);
|
|
||||||
searchRequest.types(ALERT_HISTORY_TYPE);
|
|
||||||
searchRequest.scroll(scrollTimeout);
|
|
||||||
searchRequest.preference("_primary");
|
|
||||||
return searchRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class LoadResult implements Iterable<FiredAlert> {
|
|
||||||
|
|
||||||
private final boolean succeeded;
|
|
||||||
private final List<FiredAlert> alerts;
|
|
||||||
|
|
||||||
public LoadResult(boolean succeeded, List<FiredAlert> alerts) {
|
|
||||||
this.succeeded = succeeded;
|
|
||||||
this.alerts = alerts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LoadResult(boolean succeeded) {
|
|
||||||
this.succeeded = succeeded;
|
|
||||||
this.alerts = Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<FiredAlert> iterator() {
|
|
||||||
return alerts.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean succeeded() {
|
|
||||||
return succeeded;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +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.alerts.rest.action;
|
|
||||||
|
|
||||||
import org.elasticsearch.alerts.Alert;
|
|
||||||
import org.elasticsearch.alerts.AlertsStore;
|
|
||||||
import org.elasticsearch.alerts.client.AlertsClient;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.ack.AckAlertRequest;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.ack.AckAlertResponse;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.rest.*;
|
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The rest action to ack an alert
|
|
||||||
*/
|
|
||||||
public class RestAckAlertAction extends BaseRestHandler {
|
|
||||||
|
|
||||||
private final AlertsClient alertsClient;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
protected RestAckAlertAction(Settings settings, RestController controller, Client client, AlertsClient alertsClient) {
|
|
||||||
super(settings, controller, client);
|
|
||||||
this.alertsClient = alertsClient;
|
|
||||||
controller.registerHandler(RestRequest.Method.PUT, AlertsStore.ALERT_INDEX + "/alert/{name}/_ack", this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void handleRequest(RestRequest request, RestChannel restChannel, Client client) throws Exception {
|
|
||||||
final AckAlertRequest ackAlertRequest = new AckAlertRequest();
|
|
||||||
ackAlertRequest.setAlertName(request.param("name"));
|
|
||||||
alertsClient.ackAlert(ackAlertRequest, new RestBuilderListener<AckAlertResponse>(restChannel) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RestResponse buildResponse(AckAlertResponse ackAlertResponse, XContentBuilder builder) throws Exception {
|
|
||||||
builder.startObject();
|
|
||||||
builder.field(Alert.Parser.STATUS_FIELD.getPreferredName(), ackAlertResponse.getStatus().toString());
|
|
||||||
builder.endObject();
|
|
||||||
return new BytesRestResponse(RestStatus.OK, builder);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,70 +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.alerts.rest.action;
|
|
||||||
|
|
||||||
import org.elasticsearch.alerts.AlertsStore;
|
|
||||||
import org.elasticsearch.alerts.client.AlertsClient;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.service.AlertsServiceRequest;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.service.AlertsServiceResponse;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.rest.BaseRestHandler;
|
|
||||||
import org.elasticsearch.rest.RestChannel;
|
|
||||||
import org.elasticsearch.rest.RestController;
|
|
||||||
import org.elasticsearch.rest.RestRequest;
|
|
||||||
import org.elasticsearch.rest.action.support.AcknowledgedRestListener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
public class RestAlertServiceAction extends BaseRestHandler {
|
|
||||||
|
|
||||||
private final AlertsClient alertsClient;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
protected RestAlertServiceAction(Settings settings, RestController controller, Client client, AlertsClient alertsClient) {
|
|
||||||
super(settings, controller, client);
|
|
||||||
this.alertsClient = alertsClient;
|
|
||||||
controller.registerHandler(RestRequest.Method.PUT, AlertsStore.ALERT_INDEX + "/_restart", this);
|
|
||||||
controller.registerHandler(RestRequest.Method.PUT, AlertsStore.ALERT_INDEX + "/_start", new StartRestHandler(settings, controller, client));
|
|
||||||
controller.registerHandler(RestRequest.Method.PUT, AlertsStore.ALERT_INDEX + "/_stop", new StopRestHandler(settings, controller, client));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void handleRequest(RestRequest request, RestChannel channel, Client client) throws Exception {
|
|
||||||
AlertsServiceRequest serviceRequest = new AlertsServiceRequest();
|
|
||||||
serviceRequest.restart();
|
|
||||||
alertsClient.alertService(serviceRequest, new AcknowledgedRestListener<AlertsServiceResponse>(channel));
|
|
||||||
}
|
|
||||||
|
|
||||||
final class StartRestHandler extends BaseRestHandler {
|
|
||||||
|
|
||||||
public StartRestHandler(Settings settings, RestController controller, Client client) {
|
|
||||||
super(settings, controller, client);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleRequest(RestRequest request, RestChannel channel, Client client) throws Exception {
|
|
||||||
AlertsServiceRequest serviceRequest = new AlertsServiceRequest();
|
|
||||||
serviceRequest.start();
|
|
||||||
alertsClient.alertService(serviceRequest, new AcknowledgedRestListener<AlertsServiceResponse>(channel));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final class StopRestHandler extends BaseRestHandler {
|
|
||||||
|
|
||||||
public StopRestHandler(Settings settings, RestController controller, Client client) {
|
|
||||||
super(settings, controller, client);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleRequest(RestRequest request, RestChannel channel, Client client) throws Exception {
|
|
||||||
AlertsServiceRequest serviceRequest = new AlertsServiceRequest();
|
|
||||||
serviceRequest.stop();
|
|
||||||
alertsClient.alertService(serviceRequest, new AcknowledgedRestListener<AlertsServiceResponse>(channel));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +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.alerts.rest.action;
|
|
||||||
|
|
||||||
import org.elasticsearch.alerts.AlertsStore;
|
|
||||||
import org.elasticsearch.alerts.client.AlertsClient;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.stats.AlertsStatsRequest;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.stats.AlertsStatsResponse;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.rest.*;
|
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
|
||||||
import static org.elasticsearch.rest.RestStatus.OK;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The RestAction for alerts stats
|
|
||||||
*/
|
|
||||||
public class RestAlertsStatsAction extends BaseRestHandler {
|
|
||||||
|
|
||||||
private final AlertsClient alertsClient;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
protected RestAlertsStatsAction(Settings settings, RestController controller, Client client, AlertsClient alertsClient) {
|
|
||||||
super(settings, controller, client);
|
|
||||||
this.alertsClient = alertsClient;
|
|
||||||
controller.registerHandler(GET, AlertsStore.ALERT_INDEX + "/alert/_stats", this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void handleRequest(RestRequest request, RestChannel restChannel, Client client) throws Exception {
|
|
||||||
AlertsStatsRequest statsRequest = new AlertsStatsRequest();
|
|
||||||
alertsClient.alertsStats(statsRequest, new RestBuilderListener<AlertsStatsResponse>(restChannel) {
|
|
||||||
@Override
|
|
||||||
public RestResponse buildResponse(AlertsStatsResponse alertsStatsResponse, XContentBuilder builder) throws Exception {
|
|
||||||
builder.startObject()
|
|
||||||
.field("alert_manager_state", alertsStatsResponse.getAlertManagerStarted().toString().toLowerCase(Locale.ENGLISH))
|
|
||||||
.field("alert_action_manager_started", alertsStatsResponse.isAlertActionManagerStarted())
|
|
||||||
.field("alert_action_queue_size", alertsStatsResponse.getAlertActionManagerQueueSize())
|
|
||||||
.field("number_of_alerts", alertsStatsResponse.getNumberOfRegisteredAlerts())
|
|
||||||
.field("alert_action_queue_max_size", alertsStatsResponse.getAlertActionManagerLargestQueueSize());
|
|
||||||
|
|
||||||
builder.startObject("version")
|
|
||||||
.field("number", alertsStatsResponse.getVersion().number())
|
|
||||||
.field("build_hash", alertsStatsResponse.getBuild().hash())
|
|
||||||
.field("build_timestamp", alertsStatsResponse.getBuild().timestamp())
|
|
||||||
.field("build_snapshot", alertsStatsResponse.getVersion().snapshot)
|
|
||||||
.endObject();
|
|
||||||
|
|
||||||
return new BytesRestResponse(OK, builder);
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +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.alerts.rest.action;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.get.GetResponse;
|
|
||||||
import org.elasticsearch.alerts.AlertsStore;
|
|
||||||
import org.elasticsearch.alerts.client.AlertsClient;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.get.GetAlertRequest;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.get.GetAlertResponse;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.rest.*;
|
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
|
||||||
|
|
||||||
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
|
||||||
import static org.elasticsearch.rest.RestStatus.NOT_FOUND;
|
|
||||||
import static org.elasticsearch.rest.RestStatus.OK;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The rest action to get an alert
|
|
||||||
*/
|
|
||||||
public class RestGetAlertAction extends BaseRestHandler {
|
|
||||||
|
|
||||||
private final AlertsClient alertsClient;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public RestGetAlertAction(Settings settings, RestController controller, Client client, AlertsClient alertsClient) {
|
|
||||||
super(settings, controller, client);
|
|
||||||
this.alertsClient = alertsClient;
|
|
||||||
controller.registerHandler(GET, AlertsStore.ALERT_INDEX + "/alert/{name}", this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void handleRequest(RestRequest request, RestChannel channel, Client client) throws Exception {
|
|
||||||
final GetAlertRequest getAlertRequest = new GetAlertRequest();
|
|
||||||
getAlertRequest.alertName(request.param("name"));
|
|
||||||
alertsClient.getAlert(getAlertRequest, new RestBuilderListener<GetAlertResponse>(channel) {
|
|
||||||
@Override
|
|
||||||
public RestResponse buildResponse(GetAlertResponse result, XContentBuilder builder) throws Exception {
|
|
||||||
GetResponse getResponse = result.getResponse();
|
|
||||||
builder.startObject()
|
|
||||||
.field("found", getResponse.isExists())
|
|
||||||
.field("_index", getResponse.getIndex())
|
|
||||||
.field("_type", getResponse.getType())
|
|
||||||
.field("_id", getResponse.getId())
|
|
||||||
.field("_version", getResponse.getVersion())
|
|
||||||
.field("alert", getResponse.getSource())
|
|
||||||
.endObject();
|
|
||||||
|
|
||||||
RestStatus status = OK;
|
|
||||||
if (!getResponse.isExists()) {
|
|
||||||
status = NOT_FOUND;
|
|
||||||
}
|
|
||||||
return new BytesRestResponse(status, builder);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +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.alerts.rest.action;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.index.IndexResponse;
|
|
||||||
import org.elasticsearch.alerts.AlertsStore;
|
|
||||||
import org.elasticsearch.alerts.client.AlertsClient;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.put.PutAlertRequest;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.put.PutAlertResponse;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.rest.*;
|
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
|
||||||
|
|
||||||
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
|
||||||
import static org.elasticsearch.rest.RestRequest.Method.PUT;
|
|
||||||
import static org.elasticsearch.rest.RestStatus.CREATED;
|
|
||||||
import static org.elasticsearch.rest.RestStatus.OK;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
public class RestPutAlertAction extends BaseRestHandler {
|
|
||||||
|
|
||||||
private final AlertsClient alertsClient;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public RestPutAlertAction(Settings settings, RestController controller, Client client, AlertsClient alertsClient) {
|
|
||||||
super(settings, controller, client);
|
|
||||||
this.alertsClient = alertsClient;
|
|
||||||
controller.registerHandler(POST, AlertsStore.ALERT_INDEX + "/alert/{name}", this);
|
|
||||||
controller.registerHandler(PUT, AlertsStore.ALERT_INDEX + "/alert/{name}", this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void handleRequest(RestRequest request, RestChannel channel, Client client) throws Exception {
|
|
||||||
PutAlertRequest putAlertRequest = new PutAlertRequest();
|
|
||||||
putAlertRequest.setAlertName(request.param("name"));
|
|
||||||
putAlertRequest.source(request.content(), request.contentUnsafe());
|
|
||||||
alertsClient.putAlert(putAlertRequest, new RestBuilderListener<PutAlertResponse>(channel) {
|
|
||||||
@Override
|
|
||||||
public RestResponse buildResponse(PutAlertResponse response, XContentBuilder builder) throws Exception {
|
|
||||||
IndexResponse indexResponse = response.indexResponse();
|
|
||||||
builder.startObject()
|
|
||||||
.field("_index", indexResponse.getIndex())
|
|
||||||
.field("_type", indexResponse.getType())
|
|
||||||
.field("_id", indexResponse.getId())
|
|
||||||
.field("_version", indexResponse.getVersion())
|
|
||||||
.field("created", indexResponse.isCreated());
|
|
||||||
builder.endObject();
|
|
||||||
RestStatus status = OK;
|
|
||||||
if (indexResponse.isCreated()) {
|
|
||||||
status = CREATED;
|
|
||||||
}
|
|
||||||
return new BytesRestResponse(status, builder);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,24 +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.alerts.throttle;
|
|
||||||
|
|
||||||
import org.elasticsearch.alerts.ExecutionContext;
|
|
||||||
|
|
||||||
import static org.elasticsearch.alerts.support.AlertsDateUtils.formatDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class AckThrottler implements Throttler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Result throttle(ExecutionContext ctx) {
|
|
||||||
if (ctx.alert().acked()) {
|
|
||||||
return Result.throttle("alert [" + ctx.alert().name() + "] was acked at [" + formatDate(ctx.alert().status().ackStatus().timestamp()) + "]");
|
|
||||||
}
|
|
||||||
return Result.NO;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +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.alerts.transport;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionModule;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.ack.AckAlertAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.ack.TransportAckAlertAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.delete.DeleteAlertAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.delete.TransportDeleteAlertAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.get.GetAlertAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.get.TransportGetAlertAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.put.PutAlertAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.put.TransportPutAlertAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.service.AlertsServiceAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.service.TransportAlertsServiceAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.stats.AlertsStatsAction;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.stats.TransportAlertsStatsAction;
|
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
|
||||||
import org.elasticsearch.common.inject.Module;
|
|
||||||
import org.elasticsearch.common.inject.PreProcessModule;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class AlertsTransportModule extends AbstractModule implements PreProcessModule {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void processModule(Module module) {
|
|
||||||
if (module instanceof ActionModule) {
|
|
||||||
ActionModule actionModule = (ActionModule) module;
|
|
||||||
actionModule.registerAction(PutAlertAction.INSTANCE, TransportPutAlertAction.class);
|
|
||||||
actionModule.registerAction(DeleteAlertAction.INSTANCE, TransportDeleteAlertAction.class);
|
|
||||||
actionModule.registerAction(GetAlertAction.INSTANCE, TransportGetAlertAction.class);
|
|
||||||
actionModule.registerAction(AlertsStatsAction.INSTANCE, TransportAlertsStatsAction.class);
|
|
||||||
actionModule.registerAction(AckAlertAction.INSTANCE, TransportAckAlertAction.class);
|
|
||||||
actionModule.registerAction(AlertsServiceAction.INSTANCE, TransportAlertsServiceAction.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,33 +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.alerts.transport.actions.ack;
|
|
||||||
|
|
||||||
import org.elasticsearch.alerts.client.AlertsAction;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This action acks an alert in memory, and the index
|
|
||||||
*/
|
|
||||||
public class AckAlertAction extends AlertsAction<AckAlertRequest, AckAlertResponse, AckAlertRequestBuilder> {
|
|
||||||
|
|
||||||
public static final AckAlertAction INSTANCE = new AckAlertAction();
|
|
||||||
public static final String NAME = "indices:data/write/alert/ack";
|
|
||||||
|
|
||||||
private AckAlertAction() {
|
|
||||||
super(NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AckAlertResponse newResponse() {
|
|
||||||
return new AckAlertResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AckAlertRequestBuilder newRequestBuilder(Client client) {
|
|
||||||
return new AckAlertRequestBuilder(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,39 +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.alerts.transport.actions.ack;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
|
||||||
import org.elasticsearch.action.support.master.MasterNodeOperationRequestBuilder;
|
|
||||||
import org.elasticsearch.alerts.client.AlertsClient;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A ack alert action request builder.
|
|
||||||
*/
|
|
||||||
public class AckAlertRequestBuilder extends MasterNodeOperationRequestBuilder<AckAlertRequest, AckAlertResponse, AckAlertRequestBuilder, Client> {
|
|
||||||
|
|
||||||
public AckAlertRequestBuilder(Client client) {
|
|
||||||
super(client, new AckAlertRequest());
|
|
||||||
}
|
|
||||||
|
|
||||||
public AckAlertRequestBuilder(Client client, String alertName) {
|
|
||||||
super(client, new AckAlertRequest(alertName));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the name of the alert to be ack
|
|
||||||
*/
|
|
||||||
public AckAlertRequestBuilder setAlertName(String alertName) {
|
|
||||||
this.request().setAlertName(alertName);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doExecute(final ActionListener<AckAlertResponse> listener) {
|
|
||||||
new AlertsClient(client).ackAlert(request, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,32 +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.alerts.transport.actions.delete;
|
|
||||||
|
|
||||||
import org.elasticsearch.alerts.client.AlertsAction;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This action deletes an alert from in memory, the scheduler and the index
|
|
||||||
*/
|
|
||||||
public class DeleteAlertAction extends AlertsAction<DeleteAlertRequest, DeleteAlertResponse, DeleteAlertRequestBuilder> {
|
|
||||||
|
|
||||||
public static final DeleteAlertAction INSTANCE = new DeleteAlertAction();
|
|
||||||
public static final String NAME = "indices:data/write/alert/delete";
|
|
||||||
|
|
||||||
private DeleteAlertAction() {
|
|
||||||
super(NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DeleteAlertResponse newResponse() {
|
|
||||||
return new DeleteAlertResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DeleteAlertRequestBuilder newRequestBuilder(Client client) {
|
|
||||||
return new DeleteAlertRequestBuilder(client);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +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.alerts.transport.actions.delete;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
|
||||||
import org.elasticsearch.action.support.master.MasterNodeOperationRequestBuilder;
|
|
||||||
import org.elasticsearch.alerts.client.AlertsClient;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A delete document action request builder.
|
|
||||||
*/
|
|
||||||
public class DeleteAlertRequestBuilder extends MasterNodeOperationRequestBuilder<DeleteAlertRequest, DeleteAlertResponse, DeleteAlertRequestBuilder, Client> {
|
|
||||||
|
|
||||||
public DeleteAlertRequestBuilder(Client client) {
|
|
||||||
super(client, new DeleteAlertRequest());
|
|
||||||
}
|
|
||||||
|
|
||||||
public DeleteAlertRequestBuilder(Client client, String alertName) {
|
|
||||||
super(client, new DeleteAlertRequest(alertName));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the name of the alert to be deleted
|
|
||||||
*/
|
|
||||||
public DeleteAlertRequestBuilder setAlertName(String alertName) {
|
|
||||||
this.request().setAlertName(alertName);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doExecute(final ActionListener<DeleteAlertResponse> listener) {
|
|
||||||
new AlertsClient(client).deleteAlert(request, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,32 +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.alerts.transport.actions.get;
|
|
||||||
|
|
||||||
import org.elasticsearch.alerts.client.AlertsAction;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This action gets an alert by name
|
|
||||||
*/
|
|
||||||
public class GetAlertAction extends AlertsAction<GetAlertRequest, GetAlertResponse, GetAlertRequestBuilder> {
|
|
||||||
|
|
||||||
public static final GetAlertAction INSTANCE = new GetAlertAction();
|
|
||||||
public static final String NAME = "indices:data/read/alert/get";
|
|
||||||
|
|
||||||
private GetAlertAction() {
|
|
||||||
super(NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GetAlertResponse newResponse() {
|
|
||||||
return new GetAlertResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GetAlertRequestBuilder newRequestBuilder(Client client) {
|
|
||||||
return new GetAlertRequestBuilder(client);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +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.alerts.transport.actions.put;
|
|
||||||
|
|
||||||
import org.elasticsearch.alerts.client.AlertsAction;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This action puts an alert into the alert index and adds it to the scheduler
|
|
||||||
*/
|
|
||||||
public class PutAlertAction extends AlertsAction<PutAlertRequest, PutAlertResponse, PutAlertRequestBuilder> {
|
|
||||||
|
|
||||||
public static final PutAlertAction INSTANCE = new PutAlertAction();
|
|
||||||
public static final String NAME = "indices:data/write/alert/put";
|
|
||||||
|
|
||||||
private PutAlertAction() {
|
|
||||||
super(NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PutAlertRequestBuilder newRequestBuilder(Client client) {
|
|
||||||
return new PutAlertRequestBuilder(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PutAlertResponse newResponse() {
|
|
||||||
return new PutAlertResponse();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,119 +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.alerts.transport.actions.put;
|
|
||||||
|
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionRequestValidationException;
|
|
||||||
import org.elasticsearch.action.ValidateActions;
|
|
||||||
import org.elasticsearch.action.support.master.MasterNodeOperationRequest;
|
|
||||||
import org.elasticsearch.alerts.client.AlertSourceBuilder;
|
|
||||||
import org.elasticsearch.client.Requests;
|
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentType;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This request class contains the data needed to create an alert along with the name of the alert
|
|
||||||
* the name of the alert will become the ID of the indexed document.
|
|
||||||
*/
|
|
||||||
public class PutAlertRequest extends MasterNodeOperationRequest<PutAlertRequest> {
|
|
||||||
|
|
||||||
private String alertName;
|
|
||||||
private BytesReference alertSource;
|
|
||||||
private boolean alertSourceUnsafe;
|
|
||||||
|
|
||||||
public PutAlertRequest() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param alertSource The alertSource
|
|
||||||
*/
|
|
||||||
public PutAlertRequest(BytesReference alertSource) {
|
|
||||||
this.alertSource = alertSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The name that will be the ID of the indexed document
|
|
||||||
*/
|
|
||||||
public String getAlertName() {
|
|
||||||
return alertName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the alert name
|
|
||||||
*/
|
|
||||||
public void setAlertName(String alertName) {
|
|
||||||
this.alertName = alertName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The source of the alert
|
|
||||||
*/
|
|
||||||
public BytesReference getAlertSource() {
|
|
||||||
return alertSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the source of the alert
|
|
||||||
*/
|
|
||||||
public void source(AlertSourceBuilder source) {
|
|
||||||
source(source.buildAsBytes(XContentType.JSON));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the source of the alert
|
|
||||||
*/
|
|
||||||
public void source(BytesReference alertSource) {
|
|
||||||
this.alertSource = alertSource;
|
|
||||||
this.alertSourceUnsafe = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the source of the alert with boolean to control source safety
|
|
||||||
*/
|
|
||||||
public void source(BytesReference alertSource, boolean alertSourceUnsafe) {
|
|
||||||
this.alertSource = alertSource;
|
|
||||||
this.alertSourceUnsafe = alertSourceUnsafe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void beforeLocalFork() {
|
|
||||||
if (alertSourceUnsafe) {
|
|
||||||
alertSource = alertSource.copyBytesArray();
|
|
||||||
alertSourceUnsafe = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ActionRequestValidationException validate() {
|
|
||||||
ActionRequestValidationException validationException = null;
|
|
||||||
if (alertName == null) {
|
|
||||||
validationException = ValidateActions.addValidationError("alertName is missing", validationException);
|
|
||||||
}
|
|
||||||
if (alertSource == null) {
|
|
||||||
validationException = ValidateActions.addValidationError("alertSource is missing", validationException);
|
|
||||||
}
|
|
||||||
return validationException;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readFrom(StreamInput in) throws IOException {
|
|
||||||
super.readFrom(in);
|
|
||||||
alertName = in.readString();
|
|
||||||
alertSource = in.readBytesReference();
|
|
||||||
alertSourceUnsafe = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
|
||||||
super.writeTo(out);
|
|
||||||
out.writeString(alertName);
|
|
||||||
out.writeBytesReference(alertSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,57 +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.alerts.transport.actions.put;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
|
||||||
import org.elasticsearch.action.support.master.MasterNodeOperationRequestBuilder;
|
|
||||||
import org.elasticsearch.alerts.client.AlertSourceBuilder;
|
|
||||||
import org.elasticsearch.alerts.client.AlertsClient;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Builder to build a PutAlertRequest
|
|
||||||
*/
|
|
||||||
public class PutAlertRequestBuilder extends MasterNodeOperationRequestBuilder<PutAlertRequest, PutAlertResponse, PutAlertRequestBuilder, Client> {
|
|
||||||
|
|
||||||
public PutAlertRequestBuilder(Client client) {
|
|
||||||
super(client, new PutAlertRequest());
|
|
||||||
}
|
|
||||||
|
|
||||||
public PutAlertRequestBuilder(Client client, String alertName) {
|
|
||||||
super(client, new PutAlertRequest());
|
|
||||||
request.setAlertName(alertName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param alertName The alert name to be created
|
|
||||||
*/
|
|
||||||
public PutAlertRequestBuilder alertName(String alertName){
|
|
||||||
request.setAlertName(alertName);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param source the source of the alert to be created
|
|
||||||
*/
|
|
||||||
public PutAlertRequestBuilder source(BytesReference source) {
|
|
||||||
request.source(source);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param source the source of the alert to be created
|
|
||||||
*/
|
|
||||||
public PutAlertRequestBuilder source(AlertSourceBuilder source) {
|
|
||||||
request.source(source);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doExecute(ActionListener<PutAlertResponse> listener) {
|
|
||||||
new AlertsClient(client).putAlert(request, listener);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +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.alerts.transport.actions.service;
|
|
||||||
|
|
||||||
import org.elasticsearch.alerts.client.AlertsAction;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
public class AlertsServiceAction extends AlertsAction<AlertsServiceRequest, AlertsServiceResponse, AlertsServiceRequestBuilder> {
|
|
||||||
|
|
||||||
public static final AlertsServiceAction INSTANCE = new AlertsServiceAction();
|
|
||||||
public static final String NAME = "cluster:admin/alerts/service";
|
|
||||||
|
|
||||||
private AlertsServiceAction() {
|
|
||||||
super(NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AlertsServiceResponse newResponse() {
|
|
||||||
return new AlertsServiceResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AlertsServiceRequestBuilder newRequestBuilder(Client client) {
|
|
||||||
return new AlertsServiceRequestBuilder(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,49 +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.alerts.transport.actions.service;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
|
||||||
import org.elasticsearch.action.support.master.MasterNodeOperationRequestBuilder;
|
|
||||||
import org.elasticsearch.alerts.client.AlertsClient;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
public class AlertsServiceRequestBuilder extends MasterNodeOperationRequestBuilder<AlertsServiceRequest, AlertsServiceResponse, AlertsServiceRequestBuilder, Client> {
|
|
||||||
|
|
||||||
public AlertsServiceRequestBuilder(Client client) {
|
|
||||||
super(client, new AlertsServiceRequest());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts alerting if not already started.
|
|
||||||
*/
|
|
||||||
public AlertsServiceRequestBuilder start() {
|
|
||||||
request.start();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops alerting if not already stopped.
|
|
||||||
*/
|
|
||||||
public AlertsServiceRequestBuilder stop() {
|
|
||||||
request.stop();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts and stops alerting.
|
|
||||||
*/
|
|
||||||
public AlertsServiceRequestBuilder restart() {
|
|
||||||
request.restart();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doExecute(ActionListener<AlertsServiceResponse> listener) {
|
|
||||||
new AlertsClient(client).alertService(request, listener);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +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.alerts.transport.actions.stats;
|
|
||||||
|
|
||||||
import org.elasticsearch.alerts.client.AlertsAction;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This Action gets the stats for the alert plugin
|
|
||||||
*/
|
|
||||||
public class AlertsStatsAction extends AlertsAction<AlertsStatsRequest, AlertsStatsResponse, AlertsStatsRequestBuilder> {
|
|
||||||
|
|
||||||
public static final AlertsStatsAction INSTANCE = new AlertsStatsAction();
|
|
||||||
public static final String NAME = "cluster/alerts/stats";
|
|
||||||
|
|
||||||
private AlertsStatsAction() {
|
|
||||||
super(NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AlertsStatsResponse newResponse() {
|
|
||||||
return new AlertsStatsResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AlertsStatsRequestBuilder newRequestBuilder(Client client) {
|
|
||||||
return new AlertsStatsRequestBuilder(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,31 +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.alerts.transport.actions.stats;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
|
||||||
import org.elasticsearch.action.support.master.MasterNodeOperationRequestBuilder;
|
|
||||||
import org.elasticsearch.alerts.client.AlertsClient;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An alert stats document action request builder.
|
|
||||||
*/
|
|
||||||
public class AlertsStatsRequestBuilder extends MasterNodeOperationRequestBuilder<AlertsStatsRequest, AlertsStatsResponse, AlertsStatsRequestBuilder, Client> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The constructor for the AlertsStatsRequestBuilder
|
|
||||||
*/
|
|
||||||
public AlertsStatsRequestBuilder(Client client) {
|
|
||||||
super(client, new AlertsStatsRequest());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doExecute(final ActionListener<AlertsStatsResponse> listener) {
|
|
||||||
new AlertsClient(client).alertsStats(request, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,133 +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.alerts.transport.actions.stats;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionResponse;
|
|
||||||
import org.elasticsearch.alerts.AlertsBuild;
|
|
||||||
import org.elasticsearch.alerts.AlertsService;
|
|
||||||
import org.elasticsearch.alerts.AlertsVersion;
|
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The AlertStatsResponse response
|
|
||||||
*/
|
|
||||||
public class AlertsStatsResponse extends ActionResponse {
|
|
||||||
|
|
||||||
private AlertsVersion version;
|
|
||||||
private AlertsBuild build;
|
|
||||||
private long numberOfRegisteredAlerts;
|
|
||||||
private AlertsService.State alertManagerState;
|
|
||||||
private boolean alertActionManagerStarted;
|
|
||||||
private long alertActionManagerQueueSize;
|
|
||||||
private long alertActionManagerLargestQueueSize;
|
|
||||||
|
|
||||||
public AlertsStatsResponse() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The current queue size in the alert action manager
|
|
||||||
*/
|
|
||||||
public long getAlertActionManagerQueueSize() {
|
|
||||||
return alertActionManagerQueueSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAlertActionManagerQueueSize(long alertActionManagerQueueSize) {
|
|
||||||
this.alertActionManagerQueueSize = alertActionManagerQueueSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The number of alerts currently registered in the system
|
|
||||||
*/
|
|
||||||
public long getNumberOfRegisteredAlerts() {
|
|
||||||
return numberOfRegisteredAlerts;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setNumberOfRegisteredAlerts(long numberOfRegisteredAlerts) {
|
|
||||||
this.numberOfRegisteredAlerts = numberOfRegisteredAlerts;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the state of the alert manager.
|
|
||||||
*/
|
|
||||||
public AlertsService.State getAlertManagerStarted() {
|
|
||||||
return alertManagerState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAlertManagerState(AlertsService.State alertManagerState) {
|
|
||||||
this.alertManagerState = alertManagerState;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code true} if the alert action manager is started
|
|
||||||
*/
|
|
||||||
public boolean isAlertActionManagerStarted() {
|
|
||||||
return alertActionManagerStarted;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAlertActionManagerStarted(boolean alertActionManagerStarted) {
|
|
||||||
this.alertActionManagerStarted = alertActionManagerStarted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The largest queue size the alert action manager queue has grown to
|
|
||||||
*/
|
|
||||||
public long getAlertActionManagerLargestQueueSize() {
|
|
||||||
return alertActionManagerLargestQueueSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAlertActionManagerLargestQueueSize(long alertActionManagerLargestQueueSize) {
|
|
||||||
this.alertActionManagerLargestQueueSize = alertActionManagerLargestQueueSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The alerts plugin version.
|
|
||||||
*/
|
|
||||||
public AlertsVersion getVersion() {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setVersion(AlertsVersion version) {
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The alerts plugin build information.
|
|
||||||
*/
|
|
||||||
public AlertsBuild getBuild() {
|
|
||||||
return build;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setBuild(AlertsBuild build) {
|
|
||||||
this.build = build;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readFrom(StreamInput in) throws IOException {
|
|
||||||
super.readFrom(in);
|
|
||||||
numberOfRegisteredAlerts = in.readLong();
|
|
||||||
alertActionManagerQueueSize = in.readLong();
|
|
||||||
alertActionManagerLargestQueueSize = in.readLong();
|
|
||||||
alertManagerState = AlertsService.State.fromId(in.readByte());
|
|
||||||
alertActionManagerStarted = in.readBoolean();
|
|
||||||
version = AlertsVersion.readVersion(in);
|
|
||||||
build = AlertsBuild.readBuild(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
|
||||||
super.writeTo(out);
|
|
||||||
out.writeLong(numberOfRegisteredAlerts);
|
|
||||||
out.writeLong(alertActionManagerQueueSize);
|
|
||||||
out.writeLong(alertActionManagerLargestQueueSize);
|
|
||||||
out.writeByte(alertManagerState.getId());
|
|
||||||
out.writeBoolean(alertActionManagerStarted);
|
|
||||||
AlertsVersion.writeVersion(version, out);
|
|
||||||
AlertsBuild.writeBuild(build, out);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,76 +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.alerts.transport.actions.stats;
|
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
|
||||||
import org.elasticsearch.action.support.ActionFilters;
|
|
||||||
import org.elasticsearch.action.support.master.TransportMasterNodeOperationAction;
|
|
||||||
import org.elasticsearch.alerts.AlertsBuild;
|
|
||||||
import org.elasticsearch.alerts.AlertsService;
|
|
||||||
import org.elasticsearch.alerts.AlertsVersion;
|
|
||||||
import org.elasticsearch.alerts.history.HistoryService;
|
|
||||||
import org.elasticsearch.cluster.ClusterService;
|
|
||||||
import org.elasticsearch.cluster.ClusterState;
|
|
||||||
import org.elasticsearch.cluster.block.ClusterBlockException;
|
|
||||||
import org.elasticsearch.cluster.block.ClusterBlockLevel;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
|
||||||
import org.elasticsearch.transport.TransportService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs the stats operation.
|
|
||||||
*/
|
|
||||||
public class TransportAlertsStatsAction extends TransportMasterNodeOperationAction<AlertsStatsRequest, AlertsStatsResponse> {
|
|
||||||
|
|
||||||
private final AlertsService alertsService;
|
|
||||||
private final HistoryService historyService;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public TransportAlertsStatsAction(Settings settings, TransportService transportService, ClusterService clusterService,
|
|
||||||
ThreadPool threadPool, ActionFilters actionFilters, AlertsService alertsService,
|
|
||||||
HistoryService historyService) {
|
|
||||||
super(settings, AlertsStatsAction.NAME, transportService, clusterService, threadPool, actionFilters);
|
|
||||||
this.alertsService = alertsService;
|
|
||||||
this.historyService = historyService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String executor() {
|
|
||||||
return ThreadPool.Names.MANAGEMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected AlertsStatsRequest newRequest() {
|
|
||||||
return new AlertsStatsRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected AlertsStatsResponse newResponse() {
|
|
||||||
return new AlertsStatsResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void masterOperation(AlertsStatsRequest request, ClusterState state, ActionListener<AlertsStatsResponse> listener) throws ElasticsearchException {
|
|
||||||
AlertsStatsResponse statsResponse = new AlertsStatsResponse();
|
|
||||||
statsResponse.setAlertManagerState(alertsService.state());
|
|
||||||
statsResponse.setAlertActionManagerStarted(historyService.started());
|
|
||||||
statsResponse.setAlertActionManagerQueueSize(historyService.queueSize());
|
|
||||||
statsResponse.setNumberOfRegisteredAlerts(alertsService.getNumberOfAlerts());
|
|
||||||
statsResponse.setAlertActionManagerLargestQueueSize(historyService.largestQueueSize());
|
|
||||||
statsResponse.setVersion(AlertsVersion.CURRENT);
|
|
||||||
statsResponse.setBuild(AlertsBuild.CURRENT);
|
|
||||||
listener.onResponse(statsResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ClusterBlockException checkBlock(AlertsStatsRequest request, ClusterState state) {
|
|
||||||
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts;
|
package org.elasticsearch.watcher;
|
||||||
|
|
||||||
import org.elasticsearch.common.io.FastStringReader;
|
import org.elasticsearch.common.io.FastStringReader;
|
||||||
import org.elasticsearch.common.io.Streams;
|
import org.elasticsearch.common.io.Streams;
|
||||||
|
@ -17,9 +17,9 @@ import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class AlertsBuild {
|
public class WatcherBuild {
|
||||||
|
|
||||||
public static final AlertsBuild CURRENT;
|
public static final WatcherBuild CURRENT;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
String hash = "NA";
|
String hash = "NA";
|
||||||
|
@ -27,7 +27,7 @@ public class AlertsBuild {
|
||||||
String timestamp = "NA";
|
String timestamp = "NA";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String properties = Streams.copyToStringFromClasspath("/alerts-build.properties");
|
String properties = Streams.copyToStringFromClasspath("/watcher-build.properties");
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
props.load(new FastStringReader(properties));
|
props.load(new FastStringReader(properties));
|
||||||
hash = props.getProperty("hash", hash);
|
hash = props.getProperty("hash", hash);
|
||||||
|
@ -42,14 +42,14 @@ public class AlertsBuild {
|
||||||
// just ignore...
|
// just ignore...
|
||||||
}
|
}
|
||||||
|
|
||||||
CURRENT = new AlertsBuild(hash, hashShort, timestamp);
|
CURRENT = new WatcherBuild(hash, hashShort, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String hash;
|
private final String hash;
|
||||||
private final String hashShort;
|
private final String hashShort;
|
||||||
private final String timestamp;
|
private final String timestamp;
|
||||||
|
|
||||||
AlertsBuild(String hash, String hashShort, String timestamp) {
|
WatcherBuild(String hash, String hashShort, String timestamp) {
|
||||||
this.hash = hash;
|
this.hash = hash;
|
||||||
this.hashShort = hashShort;
|
this.hashShort = hashShort;
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
|
@ -72,7 +72,7 @@ public class AlertsBuild {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
AlertsBuild that = (AlertsBuild) o;
|
WatcherBuild that = (WatcherBuild) o;
|
||||||
|
|
||||||
if (!hash.equals(that.hash)) return false;
|
if (!hash.equals(that.hash)) return false;
|
||||||
if (!hashShort.equals(that.hashShort)) return false;
|
if (!hashShort.equals(that.hashShort)) return false;
|
||||||
|
@ -89,14 +89,14 @@ public class AlertsBuild {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AlertsBuild readBuild(StreamInput in) throws IOException {
|
public static WatcherBuild readBuild(StreamInput in) throws IOException {
|
||||||
String hash = in.readString();
|
String hash = in.readString();
|
||||||
String hashShort = in.readString();
|
String hashShort = in.readString();
|
||||||
String timestamp = in.readString();
|
String timestamp = in.readString();
|
||||||
return new AlertsBuild(hash, hashShort, timestamp);
|
return new WatcherBuild(hash, hashShort, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeBuild(AlertsBuild build, StreamOutput out) throws IOException {
|
public static void writeBuild(WatcherBuild build, StreamOutput out) throws IOException {
|
||||||
out.writeString(build.hash());
|
out.writeString(build.hash());
|
||||||
out.writeString(build.hashShort());
|
out.writeString(build.hashShort());
|
||||||
out.writeString(build.timestamp());
|
out.writeString(build.timestamp());
|
|
@ -3,20 +3,20 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts;
|
package org.elasticsearch.watcher;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base class for all alerts exceptions
|
* A base class for all watcher exceptions
|
||||||
*/
|
*/
|
||||||
public class AlertsException extends ElasticsearchException {
|
public class WatcherException extends ElasticsearchException {
|
||||||
|
|
||||||
public AlertsException(String msg) {
|
public WatcherException(String msg) {
|
||||||
super(msg);
|
super(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlertsException(String msg, Throwable cause) {
|
public WatcherException(String msg, Throwable cause) {
|
||||||
super(msg, cause);
|
super(msg, cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts;
|
package org.elasticsearch.watcher;
|
||||||
|
|
||||||
import org.elasticsearch.cluster.ClusterChangedEvent;
|
import org.elasticsearch.cluster.ClusterChangedEvent;
|
||||||
import org.elasticsearch.cluster.ClusterService;
|
import org.elasticsearch.cluster.ClusterService;
|
||||||
|
@ -16,34 +16,35 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.gateway.GatewayService;
|
import org.elasticsearch.gateway.GatewayService;
|
||||||
import org.elasticsearch.indices.IndicesService;
|
import org.elasticsearch.indices.IndicesService;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
|
import org.elasticsearch.watcher.watch.WatchService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class AlertsLifeCycleService extends AbstractComponent implements ClusterStateListener {
|
public class WatcherLifeCycleService extends AbstractComponent implements ClusterStateListener {
|
||||||
|
|
||||||
private final ThreadPool threadPool;
|
private final ThreadPool threadPool;
|
||||||
private final AlertsService alertsService;
|
private final WatchService watchService;
|
||||||
private final ClusterService clusterService;
|
private final ClusterService clusterService;
|
||||||
|
|
||||||
// Maybe this should be a setting in the cluster settings?
|
// Maybe this should be a setting in the cluster settings?
|
||||||
private volatile boolean manuallyStopped;
|
private volatile boolean manuallyStopped;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public AlertsLifeCycleService(Settings settings, ClusterService clusterService, IndicesService indicesService, ThreadPool threadPool, AlertsService alertsService) {
|
public WatcherLifeCycleService(Settings settings, ClusterService clusterService, IndicesService indicesService, ThreadPool threadPool, WatchService watchService) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.clusterService = clusterService;
|
this.clusterService = clusterService;
|
||||||
this.threadPool = threadPool;
|
this.threadPool = threadPool;
|
||||||
this.alertsService = alertsService;
|
this.watchService = watchService;
|
||||||
clusterService.add(this);
|
clusterService.add(this);
|
||||||
// Close if the indices service is being stopped, so we don't run into search failures (locally) that will
|
// Close if the indices service is being stopped, so we don't run into search failures (locally) that will
|
||||||
// happen because we're shutting down and an alert is scheduled.
|
// happen because we're shutting down and an watch is scheduled.
|
||||||
indicesService.addLifecycleListener(new LifecycleListener() {
|
indicesService.addLifecycleListener(new LifecycleListener() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeStop() {
|
public void beforeStop() {
|
||||||
stop(false);
|
stop(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
manuallyStopped = !settings.getAsBoolean("alerts.start_immediately", true);
|
manuallyStopped = !settings.getAsBoolean("watcher.start_immediately", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
|
@ -55,19 +56,19 @@ public class AlertsLifeCycleService extends AbstractComponent implements Cluster
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void start(ClusterState state) {
|
private synchronized void start(ClusterState state) {
|
||||||
alertsService.start(state);
|
watchService.start(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void stop(boolean manual) {
|
private synchronized void stop(boolean manual) {
|
||||||
manuallyStopped = manual;
|
manuallyStopped = manual;
|
||||||
alertsService.stop();
|
watchService.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clusterChanged(final ClusterChangedEvent event) {
|
public void clusterChanged(final ClusterChangedEvent event) {
|
||||||
if (!event.localNodeMaster()) {
|
if (!event.localNodeMaster()) {
|
||||||
// We're no longer the master so we need to stop alerting.
|
// We're no longer the master so we need to stop the watcher.
|
||||||
// Stopping alerting may take a while since it will wait on the scheduler to complete shutdown,
|
// Stopping the watcher may take a while since it will wait on the scheduler to complete shutdown,
|
||||||
// so we fork here so that we don't wait too long. Other events may need to be processed and
|
// so we fork here so that we don't wait too long. Other events may need to be processed and
|
||||||
// other cluster state listeners may need to be executed as well for this event.
|
// other cluster state listeners may need to be executed as well for this event.
|
||||||
threadPool.executor(ThreadPool.Names.GENERIC).execute(new Runnable() {
|
threadPool.executor(ThreadPool.Names.GENERIC).execute(new Runnable() {
|
||||||
|
@ -78,11 +79,11 @@ public class AlertsLifeCycleService extends AbstractComponent implements Cluster
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (event.state().blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK)) {
|
if (event.state().blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK)) {
|
||||||
// wait until the gateway has recovered from disk, otherwise we think may not have .alerts and
|
// wait until the gateway has recovered from disk, otherwise we think may not have .watchs and
|
||||||
// a .alerts_history index, but they may not have been restored from the cluster state on disk
|
// a .watch_history index, but they may not have been restored from the cluster state on disk
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (alertsService.state() == AlertsService.State.STOPPED && !manuallyStopped) {
|
if (watchService.state() == WatchService.State.STOPPED && !manuallyStopped) {
|
||||||
threadPool.executor(ThreadPool.Names.GENERIC).execute(new Runnable() {
|
threadPool.executor(ThreadPool.Names.GENERIC).execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
|
||||||
|
import org.elasticsearch.watcher.actions.ActionModule;
|
||||||
|
import org.elasticsearch.watcher.client.WatcherClientModule;
|
||||||
|
import org.elasticsearch.watcher.condition.ConditionModule;
|
||||||
|
import org.elasticsearch.watcher.history.HistoryModule;
|
||||||
|
import org.elasticsearch.watcher.input.InputModule;
|
||||||
|
import org.elasticsearch.watcher.rest.WatcherRestModule;
|
||||||
|
import org.elasticsearch.watcher.scheduler.SchedulerModule;
|
||||||
|
import org.elasticsearch.watcher.support.TemplateUtils;
|
||||||
|
import org.elasticsearch.watcher.support.clock.ClockModule;
|
||||||
|
import org.elasticsearch.watcher.support.init.InitializingModule;
|
||||||
|
import org.elasticsearch.watcher.support.template.TemplateModule;
|
||||||
|
import org.elasticsearch.watcher.transform.TransformModule;
|
||||||
|
import org.elasticsearch.watcher.transport.WatcherTransportModule;
|
||||||
|
import org.elasticsearch.common.collect.ImmutableList;
|
||||||
|
import org.elasticsearch.common.inject.AbstractModule;
|
||||||
|
import org.elasticsearch.common.inject.Module;
|
||||||
|
import org.elasticsearch.common.inject.SpawnModules;
|
||||||
|
import org.elasticsearch.watcher.watch.WatchModule;
|
||||||
|
|
||||||
|
|
||||||
|
public class WatcherModule extends AbstractModule implements SpawnModules {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<? extends Module> spawnModules() {
|
||||||
|
return ImmutableList.of(
|
||||||
|
new InitializingModule(),
|
||||||
|
new WatchModule(),
|
||||||
|
new TemplateModule(),
|
||||||
|
new ClockModule(),
|
||||||
|
new WatcherClientModule(),
|
||||||
|
new TransformModule(),
|
||||||
|
new WatcherRestModule(),
|
||||||
|
new SchedulerModule(),
|
||||||
|
new WatcherTransportModule(),
|
||||||
|
new ConditionModule(),
|
||||||
|
new InputModule(),
|
||||||
|
new ActionModule(),
|
||||||
|
new HistoryModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bind(WatcherLifeCycleService.class).asEagerSingleton();
|
||||||
|
bind(TemplateUtils.class).asEagerSingleton();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,10 +3,10 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts;
|
package org.elasticsearch.watcher;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.actions.email.service.InternalEmailService;
|
import org.elasticsearch.watcher.actions.email.service.InternalEmailService;
|
||||||
import org.elasticsearch.alerts.support.init.InitializingService;
|
import org.elasticsearch.watcher.support.init.InitializingService;
|
||||||
import org.elasticsearch.common.collect.ImmutableList;
|
import org.elasticsearch.common.collect.ImmutableList;
|
||||||
import org.elasticsearch.common.component.LifecycleComponent;
|
import org.elasticsearch.common.component.LifecycleComponent;
|
||||||
import org.elasticsearch.common.inject.Module;
|
import org.elasticsearch.common.inject.Module;
|
||||||
|
@ -18,14 +18,14 @@ import java.util.Collection;
|
||||||
|
|
||||||
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
|
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
|
||||||
|
|
||||||
public class AlertsPlugin extends AbstractPlugin {
|
public class WatcherPlugin extends AbstractPlugin {
|
||||||
|
|
||||||
public static final String NAME = "alerts";
|
public static final String NAME = "watcher";
|
||||||
public static final String SCHEDULER_THREAD_POOL_NAME = "alerts_scheduler";
|
public static final String SCHEDULER_THREAD_POOL_NAME = "watcher_scheduler";
|
||||||
|
|
||||||
private final Settings settings;
|
private final Settings settings;
|
||||||
|
|
||||||
public AlertsPlugin(Settings settings) {
|
public WatcherPlugin(Settings settings) {
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,12 +34,12 @@ public class AlertsPlugin extends AbstractPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public String description() {
|
@Override public String description() {
|
||||||
return "Elasticsearch Alerts";
|
return "Elasticsearch Watcher";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Class<? extends Module>> modules() {
|
public Collection<Class<? extends Module>> modules() {
|
||||||
return ImmutableList.<Class<? extends Module>>of(AlertsModule.class);
|
return ImmutableList.<Class<? extends Module>>of(WatcherModule.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -3,18 +3,18 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts;
|
package org.elasticsearch.watcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class AlertsSettingsException extends AlertsException {
|
public class WatcherSettingsException extends WatcherException {
|
||||||
|
|
||||||
public AlertsSettingsException(String msg, Throwable cause) {
|
public WatcherSettingsException(String msg, Throwable cause) {
|
||||||
super(msg, cause);
|
super(msg, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlertsSettingsException(String msg) {
|
public WatcherSettingsException(String msg) {
|
||||||
super(msg);
|
super(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts;
|
package org.elasticsearch.watcher;
|
||||||
|
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
|
@ -17,7 +17,7 @@ import java.io.Serializable;
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public class AlertsVersion implements Serializable {
|
public class WatcherVersion implements Serializable {
|
||||||
|
|
||||||
// The logic for ID is: XXYYZZAA, where XX is major version, YY is minor version, ZZ is revision, and AA is Beta/RC indicator
|
// The logic for ID is: XXYYZZAA, where XX is major version, YY is minor version, ZZ is revision, and AA is Beta/RC indicator
|
||||||
// AA values below 50 are beta builds, and below 99 are RC builds, with 99 indicating a release
|
// AA values below 50 are beta builds, and below 99 are RC builds, with 99 indicating a release
|
||||||
|
@ -25,41 +25,41 @@ public class AlertsVersion implements Serializable {
|
||||||
|
|
||||||
// The first internal beta has already been released, without this class being here, so we start version version 2.
|
// The first internal beta has already been released, without this class being here, so we start version version 2.
|
||||||
public static final int V_1_0_0_Beta2_ID = /*00*/1000002;
|
public static final int V_1_0_0_Beta2_ID = /*00*/1000002;
|
||||||
public static final AlertsVersion V_1_0_0_Beta2 = new AlertsVersion(V_1_0_0_Beta2_ID, true, Version.V_1_4_0);
|
public static final WatcherVersion V_1_0_0_Beta2 = new WatcherVersion(V_1_0_0_Beta2_ID, true, Version.V_1_4_0);
|
||||||
|
|
||||||
public static final AlertsVersion CURRENT = V_1_0_0_Beta2;
|
public static final WatcherVersion CURRENT = V_1_0_0_Beta2;
|
||||||
|
|
||||||
public static AlertsVersion readVersion(StreamInput in) throws IOException {
|
public static WatcherVersion readVersion(StreamInput in) throws IOException {
|
||||||
return fromId(in.readVInt());
|
return fromId(in.readVInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AlertsVersion fromId(int id) {
|
public static WatcherVersion fromId(int id) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case V_1_0_0_Beta2_ID:
|
case V_1_0_0_Beta2_ID:
|
||||||
return V_1_0_0_Beta2;
|
return V_1_0_0_Beta2;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return new AlertsVersion(id, null, Version.CURRENT);
|
return new WatcherVersion(id, null, Version.CURRENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeVersion(AlertsVersion version, StreamOutput out) throws IOException {
|
public static void writeVersion(WatcherVersion version, StreamOutput out) throws IOException {
|
||||||
out.writeVInt(version.id);
|
out.writeVInt(version.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the smallest version between the 2.
|
* Returns the smallest version between the 2.
|
||||||
*/
|
*/
|
||||||
public static AlertsVersion smallest(AlertsVersion version1, AlertsVersion version2) {
|
public static WatcherVersion smallest(WatcherVersion version1, WatcherVersion version2) {
|
||||||
return version1.id < version2.id ? version1 : version2;
|
return version1.id < version2.id ? version1 : version2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the version given its string representation, current version if the argument is null or empty
|
* Returns the version given its string representation, current version if the argument is null or empty
|
||||||
*/
|
*/
|
||||||
public static AlertsVersion fromString(String version) {
|
public static WatcherVersion fromString(String version) {
|
||||||
if (!Strings.hasLength(version)) {
|
if (!Strings.hasLength(version)) {
|
||||||
return AlertsVersion.CURRENT;
|
return WatcherVersion.CURRENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] parts = version.split("\\.");
|
String[] parts = version.split("\\.");
|
||||||
|
@ -100,7 +100,7 @@ public class AlertsVersion implements Serializable {
|
||||||
public final Version minEsCompatibilityVersion;
|
public final Version minEsCompatibilityVersion;
|
||||||
// TODO: Once licencing integration has been completed license version should be added to
|
// TODO: Once licencing integration has been completed license version should be added to
|
||||||
|
|
||||||
AlertsVersion(int id, @Nullable Boolean snapshot, Version minEsCompatibilityVersion) {
|
WatcherVersion(int id, @Nullable Boolean snapshot, Version minEsCompatibilityVersion) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.major = (byte) ((id / 1000000) % 100);
|
this.major = (byte) ((id / 1000000) % 100);
|
||||||
this.minor = (byte) ((id / 10000) % 100);
|
this.minor = (byte) ((id / 10000) % 100);
|
||||||
|
@ -114,23 +114,23 @@ public class AlertsVersion implements Serializable {
|
||||||
return snapshot != null && snapshot;
|
return snapshot != null && snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean after(AlertsVersion version) {
|
public boolean after(WatcherVersion version) {
|
||||||
return version.id < id;
|
return version.id < id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onOrAfter(AlertsVersion version) {
|
public boolean onOrAfter(WatcherVersion version) {
|
||||||
return version.id <= id;
|
return version.id <= id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean before(AlertsVersion version) {
|
public boolean before(WatcherVersion version) {
|
||||||
return version.id > id;
|
return version.id > id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onOrBefore(AlertsVersion version) {
|
public boolean onOrBefore(WatcherVersion version) {
|
||||||
return version.id >= id;
|
return version.id >= id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean compatibleWith(AlertsVersion version) {
|
public boolean compatibleWith(WatcherVersion version) {
|
||||||
return version.onOrAfter(minimumCompatibilityVersion());
|
return version.onOrAfter(minimumCompatibilityVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,8 +145,8 @@ public class AlertsVersion implements Serializable {
|
||||||
* is in most of the cases the smallest major version release unless the current version
|
* is in most of the cases the smallest major version release unless the current version
|
||||||
* is a beta or RC release then the version itself is returned.
|
* is a beta or RC release then the version itself is returned.
|
||||||
*/
|
*/
|
||||||
public AlertsVersion minimumCompatibilityVersion() {
|
public WatcherVersion minimumCompatibilityVersion() {
|
||||||
return AlertsVersion.smallest(this, fromId(major * 1000000 + 99));
|
return WatcherVersion.smallest(this, fromId(major * 1000000 + 99));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -185,7 +185,7 @@ public class AlertsVersion implements Serializable {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
AlertsVersion that = (AlertsVersion) o;
|
WatcherVersion that = (WatcherVersion) o;
|
||||||
|
|
||||||
if (id != that.id) return false;
|
if (id != that.id) return false;
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions;
|
package org.elasticsearch.watcher.actions;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.ExecutionContext;
|
import org.elasticsearch.watcher.watch.WatchExecutionContext;
|
||||||
import org.elasticsearch.alerts.Payload;
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
import org.elasticsearch.alerts.transform.Transform;
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
|
@ -43,7 +43,7 @@ public abstract class Action<R extends Action.Result> implements ToXContent {
|
||||||
/**
|
/**
|
||||||
* Executes this action
|
* Executes this action
|
||||||
*/
|
*/
|
||||||
public R execute(ExecutionContext context) throws IOException {
|
public R execute(WatchExecutionContext context) throws IOException {
|
||||||
Payload payload = context.payload();
|
Payload payload = context.payload();
|
||||||
Transform.Result transformResult = null;
|
Transform.Result transformResult = null;
|
||||||
if (transform != null) {
|
if (transform != null) {
|
||||||
|
@ -57,7 +57,7 @@ public abstract class Action<R extends Action.Result> implements ToXContent {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract R execute(ExecutionContext context, Payload payload) throws IOException;
|
protected abstract R execute(WatchExecutionContext context, Payload payload) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses xcontent to a concrete action of the same type.
|
* Parses xcontent to a concrete action of the same type.
|
|
@ -3,12 +3,12 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions;
|
package org.elasticsearch.watcher.actions;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.actions.email.EmailAction;
|
import org.elasticsearch.watcher.actions.email.EmailAction;
|
||||||
import org.elasticsearch.alerts.actions.index.IndexAction;
|
import org.elasticsearch.watcher.actions.index.IndexAction;
|
||||||
import org.elasticsearch.alerts.actions.webhook.WebhookAction;
|
import org.elasticsearch.watcher.actions.webhook.WebhookAction;
|
||||||
import org.elasticsearch.alerts.support.Script;
|
import org.elasticsearch.watcher.support.Script;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
|
@ -3,14 +3,14 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions;
|
package org.elasticsearch.watcher.actions;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.AlertsException;
|
import org.elasticsearch.watcher.WatcherException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ActionException extends AlertsException {
|
public class ActionException extends WatcherException {
|
||||||
|
|
||||||
public ActionException(String msg) {
|
public ActionException(String msg) {
|
||||||
super(msg);
|
super(msg);
|
|
@ -3,14 +3,14 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions;
|
package org.elasticsearch.watcher.actions;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.actions.email.EmailAction;
|
import org.elasticsearch.watcher.actions.email.EmailAction;
|
||||||
import org.elasticsearch.alerts.actions.email.service.EmailService;
|
import org.elasticsearch.watcher.actions.email.service.EmailService;
|
||||||
import org.elasticsearch.alerts.actions.email.service.InternalEmailService;
|
import org.elasticsearch.watcher.actions.email.service.InternalEmailService;
|
||||||
import org.elasticsearch.alerts.actions.index.IndexAction;
|
import org.elasticsearch.watcher.actions.index.IndexAction;
|
||||||
import org.elasticsearch.alerts.actions.webhook.HttpClient;
|
import org.elasticsearch.watcher.actions.webhook.HttpClient;
|
||||||
import org.elasticsearch.alerts.actions.webhook.WebhookAction;
|
import org.elasticsearch.watcher.actions.webhook.WebhookAction;
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
import org.elasticsearch.common.inject.AbstractModule;
|
||||||
import org.elasticsearch.common.inject.multibindings.MapBinder;
|
import org.elasticsearch.common.inject.multibindings.MapBinder;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions;
|
package org.elasticsearch.watcher.actions;
|
||||||
|
|
||||||
import org.elasticsearch.common.collect.ImmutableMap;
|
import org.elasticsearch.common.collect.ImmutableMap;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions;
|
package org.elasticsearch.watcher.actions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions;
|
package org.elasticsearch.watcher.actions;
|
||||||
|
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
@ -3,17 +3,17 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.email;
|
package org.elasticsearch.watcher.actions.email;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.ExecutionContext;
|
import org.elasticsearch.watcher.watch.WatchExecutionContext;
|
||||||
import org.elasticsearch.alerts.Payload;
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
import org.elasticsearch.alerts.actions.Action;
|
import org.elasticsearch.watcher.actions.Action;
|
||||||
import org.elasticsearch.alerts.actions.ActionSettingsException;
|
import org.elasticsearch.watcher.actions.ActionSettingsException;
|
||||||
import org.elasticsearch.alerts.actions.email.service.*;
|
import org.elasticsearch.watcher.actions.email.service.*;
|
||||||
import org.elasticsearch.alerts.support.Variables;
|
import org.elasticsearch.watcher.support.Variables;
|
||||||
import org.elasticsearch.alerts.support.template.Template;
|
import org.elasticsearch.watcher.support.template.Template;
|
||||||
import org.elasticsearch.alerts.transform.Transform;
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
import org.elasticsearch.alerts.transform.TransformRegistry;
|
import org.elasticsearch.watcher.transform.TransformRegistry;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
import org.elasticsearch.common.component.AbstractComponent;
|
||||||
|
@ -67,7 +67,7 @@ public class EmailAction extends Action<EmailAction.Result> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Result execute(ExecutionContext ctx, Payload payload) throws IOException {
|
protected Result execute(WatchExecutionContext ctx, Payload payload) throws IOException {
|
||||||
Map<String, Object> model = Variables.createCtxModel(ctx, payload);
|
Map<String, Object> model = Variables.createCtxModel(ctx, payload);
|
||||||
|
|
||||||
Email.Builder email = Email.builder()
|
Email.Builder email = Email.builder()
|
||||||
|
@ -91,8 +91,8 @@ public class EmailAction extends Action<EmailAction.Result> {
|
||||||
EmailService.EmailSent sent = emailService.send(email.build(), auth, profile, account);
|
EmailService.EmailSent sent = emailService.send(email.build(), auth, profile, account);
|
||||||
return new Result.Success(sent);
|
return new Result.Success(sent);
|
||||||
} catch (EmailException ee) {
|
} catch (EmailException ee) {
|
||||||
logger.error("could not send email for alert [{}]", ee, ctx.alert().name());
|
logger.error("could not send email for watch [{}]", ee, ctx.watch().name());
|
||||||
return new Result.Failure("could not send email for alert [" + ctx.alert().name() + "]. error: " + ee.getMessage());
|
return new Result.Failure("could not send email for watch [" + ctx.watch().name() + "]. error: " + ee.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.email.service;
|
package org.elasticsearch.watcher.actions.email.service;
|
||||||
|
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||||
|
@ -166,8 +166,8 @@ public class Account {
|
||||||
* holds email fields that can be configured on the account. These fields
|
* holds email fields that can be configured on the account. These fields
|
||||||
* will hold the default values for missing fields in email messages. Having
|
* will hold the default values for missing fields in email messages. Having
|
||||||
* the ability to create these default can substantially reduced the configuration
|
* the ability to create these default can substantially reduced the configuration
|
||||||
* needed on each alert (e.g. if all the emails are always sent to the same recipients
|
* needed on each watch (e.g. if all the emails are always sent to the same recipients
|
||||||
* one could set those here and leave them out on the alert definition).
|
* one could set those here and leave them out on the watch definition).
|
||||||
*/
|
*/
|
||||||
static class EmailDefaults {
|
static class EmailDefaults {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.email.service;
|
package org.elasticsearch.watcher.actions.email.service;
|
||||||
|
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
|
@ -3,9 +3,9 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.email.service;
|
package org.elasticsearch.watcher.actions.email.service;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.actions.email.service.support.BodyPartSource;
|
import org.elasticsearch.watcher.actions.email.service.support.BodyPartSource;
|
||||||
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.common.xcontent.XContentType;
|
import org.elasticsearch.common.xcontent.XContentType;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.email.service;
|
package org.elasticsearch.watcher.actions.email.service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.email.service;
|
package org.elasticsearch.watcher.actions.email.service;
|
||||||
|
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.base.Charsets;
|
import org.elasticsearch.common.base.Charsets;
|
||||||
|
@ -316,7 +316,7 @@ public class Email implements ToXContent {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Email build() {
|
public Email build() {
|
||||||
assert id != null : "email id should not be null (should be set to the alert id";
|
assert id != null : "email id should not be null (should be set to the watch id";
|
||||||
return new Email(id, from, replyTo, priority, sentDate, to, cc, bcc, subject, textBody, htmlBody, attachments.build(), inlines.build());
|
return new Email(id, from, replyTo, priority, sentDate, to, cc, bcc, subject, textBody, htmlBody, attachments.build(), inlines.build());
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.email.service;
|
package org.elasticsearch.watcher.actions.email.service;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.actions.ActionException;
|
import org.elasticsearch.watcher.actions.ActionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.email.service;
|
package org.elasticsearch.watcher.actions.email.service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.email.service;
|
package org.elasticsearch.watcher.actions.email.service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
|
@ -3,9 +3,9 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.email.service;
|
package org.elasticsearch.watcher.actions.email.service;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.actions.email.service.support.BodyPartSource;
|
import org.elasticsearch.watcher.actions.email.service.support.BodyPartSource;
|
||||||
import org.elasticsearch.common.bytes.BytesArray;
|
import org.elasticsearch.common.bytes.BytesArray;
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
import org.elasticsearch.common.inject.Provider;
|
import org.elasticsearch.common.inject.Provider;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.email.service;
|
package org.elasticsearch.watcher.actions.email.service;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.common.component.AbstractLifecycleComponent;
|
import org.elasticsearch.common.component.AbstractLifecycleComponent;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.email.service;
|
package org.elasticsearch.watcher.actions.email.service;
|
||||||
|
|
||||||
import org.elasticsearch.common.base.Charsets;
|
import org.elasticsearch.common.base.Charsets;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.email.service.support;
|
package org.elasticsearch.watcher.actions.email.service.support;
|
||||||
|
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
|
|
|
@ -3,19 +3,19 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.index;
|
package org.elasticsearch.watcher.actions.index;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.action.index.IndexRequest;
|
import org.elasticsearch.action.index.IndexRequest;
|
||||||
import org.elasticsearch.action.index.IndexResponse;
|
import org.elasticsearch.action.index.IndexResponse;
|
||||||
import org.elasticsearch.alerts.ExecutionContext;
|
import org.elasticsearch.watcher.watch.WatchExecutionContext;
|
||||||
import org.elasticsearch.alerts.Payload;
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
import org.elasticsearch.alerts.actions.Action;
|
import org.elasticsearch.watcher.actions.Action;
|
||||||
import org.elasticsearch.alerts.actions.ActionException;
|
import org.elasticsearch.watcher.actions.ActionException;
|
||||||
import org.elasticsearch.alerts.actions.ActionSettingsException;
|
import org.elasticsearch.watcher.actions.ActionSettingsException;
|
||||||
import org.elasticsearch.alerts.support.init.proxy.ClientProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
import org.elasticsearch.alerts.transform.Transform;
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
import org.elasticsearch.alerts.transform.TransformRegistry;
|
import org.elasticsearch.watcher.transform.TransformRegistry;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
import org.elasticsearch.common.component.AbstractComponent;
|
||||||
|
@ -54,7 +54,7 @@ public class IndexAction extends Action<IndexAction.Result> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Result execute(ExecutionContext ctx, Payload payload) throws IOException {
|
protected Result execute(WatchExecutionContext ctx, Payload payload) throws IOException {
|
||||||
IndexRequest indexRequest = new IndexRequest();
|
IndexRequest indexRequest = new IndexRequest();
|
||||||
indexRequest.index(index);
|
indexRequest.index(index);
|
||||||
indexRequest.type(type);
|
indexRequest.type(type);
|
||||||
|
@ -66,7 +66,7 @@ public class IndexAction extends Action<IndexAction.Result> {
|
||||||
resultBuilder.endObject();
|
resultBuilder.endObject();
|
||||||
indexRequest.source(resultBuilder);
|
indexRequest.source(resultBuilder);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
logger.error("failed to index result for alert [{}]", ioe, ctx.alert().name());
|
logger.error("failed to index result for watch [{}]", ioe, ctx.watch().name());
|
||||||
return new Result(null, "failed to build index request. " + ioe.getMessage(), false);
|
return new Result(null, "failed to build index request. " + ioe.getMessage(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ public class IndexAction extends Action<IndexAction.Result> {
|
||||||
data.put("index", response.getIndex());
|
data.put("index", response.getIndex());
|
||||||
return new Result(new Payload.Simple(data), null, response.isCreated());
|
return new Result(new Payload.Simple(data), null, response.isCreated());
|
||||||
} catch (ElasticsearchException e) {
|
} catch (ElasticsearchException e) {
|
||||||
logger.error("failed to index result for alert [{}]", e, ctx.alert().name());
|
logger.error("failed to index result for watch [{}]", e, ctx.watch().name());
|
||||||
return new Result(null, "failed to build index request. " + e.getMessage(), false);
|
return new Result(null, "failed to build index request. " + e.getMessage(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.webhook;
|
package org.elasticsearch.watcher.actions.webhook;
|
||||||
|
|
||||||
import org.elasticsearch.common.base.Charsets;
|
import org.elasticsearch.common.base.Charsets;
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
import org.elasticsearch.common.component.AbstractComponent;
|
|
@ -3,20 +3,20 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.actions.webhook;
|
package org.elasticsearch.watcher.actions.webhook;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.AlertsSettingsException;
|
import org.elasticsearch.watcher.WatcherSettingsException;
|
||||||
import org.elasticsearch.alerts.ExecutionContext;
|
import org.elasticsearch.watcher.watch.WatchExecutionContext;
|
||||||
import org.elasticsearch.alerts.Payload;
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
import org.elasticsearch.alerts.actions.Action;
|
import org.elasticsearch.watcher.actions.Action;
|
||||||
import org.elasticsearch.alerts.actions.ActionException;
|
import org.elasticsearch.watcher.actions.ActionException;
|
||||||
import org.elasticsearch.alerts.actions.ActionSettingsException;
|
import org.elasticsearch.watcher.actions.ActionSettingsException;
|
||||||
import org.elasticsearch.alerts.support.Script;
|
import org.elasticsearch.watcher.support.Script;
|
||||||
import org.elasticsearch.alerts.support.Variables;
|
import org.elasticsearch.watcher.support.Variables;
|
||||||
import org.elasticsearch.alerts.support.template.Template;
|
import org.elasticsearch.watcher.support.template.Template;
|
||||||
import org.elasticsearch.alerts.support.template.XContentTemplate;
|
import org.elasticsearch.watcher.support.template.XContentTemplate;
|
||||||
import org.elasticsearch.alerts.transform.Transform;
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
import org.elasticsearch.alerts.transform.TransformRegistry;
|
import org.elasticsearch.watcher.transform.TransformRegistry;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
import org.elasticsearch.common.component.AbstractComponent;
|
||||||
|
@ -57,7 +57,7 @@ public class WebhookAction extends Action<WebhookAction.Result> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Result execute(ExecutionContext ctx, Payload payload) throws IOException {
|
protected Result execute(WatchExecutionContext ctx, Payload payload) throws IOException {
|
||||||
Map<String, Object> model = Variables.createCtxModel(ctx, payload);
|
Map<String, Object> model = Variables.createCtxModel(ctx, payload);
|
||||||
String urlText = url.render(model);
|
String urlText = url.render(model);
|
||||||
String bodyText = body != null ? body.render(model) : XContentTemplate.YAML.render(model);
|
String bodyText = body != null ? body.render(model) : XContentTemplate.YAML.render(model);
|
||||||
|
@ -74,7 +74,7 @@ public class WebhookAction extends Action<WebhookAction.Result> {
|
||||||
return new Result.Executed(status, urlText, bodyText);
|
return new Result.Executed(status, urlText, bodyText);
|
||||||
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
logger.error("failed to connect to [{}] for alert [{}]", ioe, urlText, ctx.alert().name());
|
logger.error("failed to connect to [{}] for watch [{}]", ioe, urlText, ctx.watch().name());
|
||||||
return new Result.Failure("failed to send http request. " + ioe.getMessage());
|
return new Result.Failure("failed to send http request. " + ioe.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ public class WebhookAction extends Action<WebhookAction.Result> {
|
||||||
try {
|
try {
|
||||||
urlTemplate = templateParser.parse(parser);
|
urlTemplate = templateParser.parse(parser);
|
||||||
} catch (Template.Parser.ParseException pe) {
|
} catch (Template.Parser.ParseException pe) {
|
||||||
throw new AlertsSettingsException("could not parse webhook action [url] template", pe);
|
throw new WatcherSettingsException("could not parse webhook action [url] template", pe);
|
||||||
}
|
}
|
||||||
} else if (BODY_FIELD.match(currentFieldName)) {
|
} else if (BODY_FIELD.match(currentFieldName)) {
|
||||||
try {
|
try {
|
|
@ -3,16 +3,16 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.client;
|
package org.elasticsearch.watcher.client;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.Alert;
|
import org.elasticsearch.watcher.watch.Watch;
|
||||||
import org.elasticsearch.alerts.actions.Action;
|
import org.elasticsearch.watcher.actions.Action;
|
||||||
import org.elasticsearch.alerts.condition.Condition;
|
import org.elasticsearch.watcher.condition.Condition;
|
||||||
import org.elasticsearch.alerts.condition.ConditionBuilders;
|
import org.elasticsearch.watcher.condition.ConditionBuilders;
|
||||||
import org.elasticsearch.alerts.input.Input;
|
import org.elasticsearch.watcher.input.Input;
|
||||||
import org.elasticsearch.alerts.input.NoneInput;
|
import org.elasticsearch.watcher.input.NoneInput;
|
||||||
import org.elasticsearch.alerts.scheduler.schedule.Schedule;
|
import org.elasticsearch.watcher.scheduler.schedule.Schedule;
|
||||||
import org.elasticsearch.alerts.transform.Transform;
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
|
@ -29,10 +29,10 @@ import java.util.Set;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class AlertSourceBuilder implements ToXContent {
|
public class WatchSourceBuilder implements ToXContent {
|
||||||
|
|
||||||
public static AlertSourceBuilder alertSourceBuilder() {
|
public static WatchSourceBuilder watchSourceBuilder() {
|
||||||
return new AlertSourceBuilder();
|
return new WatchSourceBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Schedule schedule;
|
private Schedule schedule;
|
||||||
|
@ -43,37 +43,37 @@ public class AlertSourceBuilder implements ToXContent {
|
||||||
private TimeValue throttlePeriod = null;
|
private TimeValue throttlePeriod = null;
|
||||||
private Map<String, Object> metadata;
|
private Map<String, Object> metadata;
|
||||||
|
|
||||||
public AlertSourceBuilder schedule(Schedule schedule) {
|
public WatchSourceBuilder schedule(Schedule schedule) {
|
||||||
this.schedule = schedule;
|
this.schedule = schedule;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlertSourceBuilder input(Input.SourceBuilder input) {
|
public WatchSourceBuilder input(Input.SourceBuilder input) {
|
||||||
this.input = input;
|
this.input = input;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlertSourceBuilder condition(Condition.SourceBuilder condition) {
|
public WatchSourceBuilder condition(Condition.SourceBuilder condition) {
|
||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlertSourceBuilder transform(Transform.SourceBuilder transform) {
|
public WatchSourceBuilder transform(Transform.SourceBuilder transform) {
|
||||||
this.transform = transform;
|
this.transform = transform;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlertSourceBuilder throttlePeriod(TimeValue throttlePeriod) {
|
public WatchSourceBuilder throttlePeriod(TimeValue throttlePeriod) {
|
||||||
this.throttlePeriod = throttlePeriod;
|
this.throttlePeriod = throttlePeriod;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlertSourceBuilder addAction(Action.SourceBuilder action) {
|
public WatchSourceBuilder addAction(Action.SourceBuilder action) {
|
||||||
actions.add(action);
|
actions.add(action);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlertSourceBuilder metadata(Map<String, Object> metadata) {
|
public WatchSourceBuilder metadata(Map<String, Object> metadata) {
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -82,36 +82,36 @@ public class AlertSourceBuilder implements ToXContent {
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
|
|
||||||
builder.startObject(Alert.Parser.SCHEDULE_FIELD.getPreferredName())
|
builder.startObject(Watch.Parser.SCHEDULE_FIELD.getPreferredName())
|
||||||
.field(schedule.type(), schedule)
|
.field(schedule.type(), schedule)
|
||||||
.endObject();
|
.endObject();
|
||||||
|
|
||||||
builder.startObject(Alert.Parser.INPUT_FIELD.getPreferredName())
|
builder.startObject(Watch.Parser.INPUT_FIELD.getPreferredName())
|
||||||
.field(input.type(), input)
|
.field(input.type(), input)
|
||||||
.endObject();
|
.endObject();
|
||||||
|
|
||||||
builder.startObject(Alert.Parser.CONDITION_FIELD.getPreferredName())
|
builder.startObject(Watch.Parser.CONDITION_FIELD.getPreferredName())
|
||||||
.field(condition.type(), condition)
|
.field(condition.type(), condition)
|
||||||
.endObject();
|
.endObject();
|
||||||
|
|
||||||
if (transform != null) {
|
if (transform != null) {
|
||||||
builder.startObject(Alert.Parser.TRANSFORM_FIELD.getPreferredName())
|
builder.startObject(Watch.Parser.TRANSFORM_FIELD.getPreferredName())
|
||||||
.field(transform.type(), transform)
|
.field(transform.type(), transform)
|
||||||
.endObject();
|
.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (throttlePeriod != null) {
|
if (throttlePeriod != null) {
|
||||||
builder.field(Alert.Parser.THROTTLE_PERIOD_FIELD.getPreferredName(), throttlePeriod.getMillis());
|
builder.field(Watch.Parser.THROTTLE_PERIOD_FIELD.getPreferredName(), throttlePeriod.getMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.startArray(Alert.Parser.ACTIONS_FIELD.getPreferredName());
|
builder.startArray(Watch.Parser.ACTIONS_FIELD.getPreferredName());
|
||||||
for (Action.SourceBuilder action : actions) {
|
for (Action.SourceBuilder action : actions) {
|
||||||
builder.startObject().field(action.type(), action).endObject();
|
builder.startObject().field(action.type(), action).endObject();
|
||||||
}
|
}
|
||||||
builder.endArray();
|
builder.endArray();
|
||||||
|
|
||||||
if (metadata != null) {
|
if (metadata != null) {
|
||||||
builder.field(Alert.Parser.META_FIELD.getPreferredName(), metadata);
|
builder.field(Watch.Parser.META_FIELD.getPreferredName(), metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.endObject();
|
return builder.endObject();
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.client;
|
package org.elasticsearch.watcher.client;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionRequest;
|
import org.elasticsearch.action.ActionRequest;
|
||||||
import org.elasticsearch.action.ActionRequestBuilder;
|
import org.elasticsearch.action.ActionRequestBuilder;
|
||||||
|
@ -12,11 +12,11 @@ import org.elasticsearch.action.ClientAction;
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base alert action class.
|
* All watcher related actions should extend this base class.
|
||||||
*/
|
*/
|
||||||
public abstract class AlertsAction<Request extends ActionRequest, Response extends ActionResponse, RequestBuilder extends ActionRequestBuilder<Request, Response, RequestBuilder, Client>> extends ClientAction<Request, Response, RequestBuilder> {
|
public abstract class WatcherAction<Request extends ActionRequest, Response extends ActionResponse, RequestBuilder extends ActionRequestBuilder<Request, Response, RequestBuilder, Client>> extends ClientAction<Request, Response, RequestBuilder> {
|
||||||
|
|
||||||
protected AlertsAction(String name) {
|
protected WatcherAction(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,253 @@
|
||||||
|
/*
|
||||||
|
* 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.client;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.ActionFuture;
|
||||||
|
import org.elasticsearch.action.ActionListener;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.ack.AckWatchAction;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.ack.AckWatchRequest;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.ack.AckWatchRequestBuilder;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.ack.AckWatchResponse;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.delete.DeleteWatchAction;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.delete.DeleteWatchRequest;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.delete.DeleteWatchRequestBuilder;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.delete.DeleteWatchResponse;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.get.GetWatchAction;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.get.GetWatchRequest;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.get.GetWatchRequestBuilder;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.get.GetWatchResponse;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.put.PutWatchAction;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.put.PutWatchRequest;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.put.PutWatchRequestBuilder;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.put.PutWatchResponse;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.service.WatcherServiceAction;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.service.WatcherServiceRequest;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.service.WatcherServiceRequestBuilder;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.service.WatcherServiceResponse;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.stats.WatcherStatsAction;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.stats.WatcherStatsRequest;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.stats.WatcherStatsRequestBuilder;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.stats.WatcherStatsResponse;
|
||||||
|
import org.elasticsearch.client.Client;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public class WatcherClient {
|
||||||
|
|
||||||
|
private final Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public WatcherClient(Client client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a request builder that gets an watch by name (id)
|
||||||
|
*
|
||||||
|
* @param watchName the name (id) of the watch
|
||||||
|
* @return The request builder
|
||||||
|
*/
|
||||||
|
public GetWatchRequestBuilder prepareGetWatch(String watchName) {
|
||||||
|
return new GetWatchRequestBuilder(client, watchName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a request builder that gets an watch
|
||||||
|
*
|
||||||
|
* @return the request builder
|
||||||
|
*/
|
||||||
|
public GetWatchRequestBuilder prepareGetWatch() {
|
||||||
|
return new GetWatchRequestBuilder(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an watch from the watch index
|
||||||
|
*
|
||||||
|
* @param request The get watch request
|
||||||
|
* @param listener The listener for the get watch response containing the GetResponse for this watch
|
||||||
|
*/
|
||||||
|
public void getWatch(GetWatchRequest request, ActionListener<GetWatchResponse> listener) {
|
||||||
|
client.execute(GetWatchAction.INSTANCE, request, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an watch from the watch index
|
||||||
|
*
|
||||||
|
* @param request The get watch request with the watch name (id)
|
||||||
|
* @return The response containing the GetResponse for this watch
|
||||||
|
*/
|
||||||
|
public ActionFuture<GetWatchResponse> getWatch(GetWatchRequest request) {
|
||||||
|
return client.execute(GetWatchAction.INSTANCE, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a request builder to delete an watch by name (id)
|
||||||
|
*
|
||||||
|
* @param watchName the name (id) of the watch
|
||||||
|
* @return The request builder
|
||||||
|
*/
|
||||||
|
public DeleteWatchRequestBuilder prepareDeleteWatch(String watchName) {
|
||||||
|
return new DeleteWatchRequestBuilder(client, watchName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a request builder that deletes an watch
|
||||||
|
*
|
||||||
|
* @return The request builder
|
||||||
|
*/
|
||||||
|
public DeleteWatchRequestBuilder prepareDeleteWatch() {
|
||||||
|
return new DeleteWatchRequestBuilder(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes an watch
|
||||||
|
*
|
||||||
|
* @param request The delete request with the watch name (id) to be deleted
|
||||||
|
* @param listener The listener for the delete watch response containing the DeleteResponse for this action
|
||||||
|
*/
|
||||||
|
public void deleteWatch(DeleteWatchRequest request, ActionListener<DeleteWatchResponse> listener) {
|
||||||
|
client.execute(DeleteWatchAction.INSTANCE, request, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes an watch
|
||||||
|
*
|
||||||
|
* @param request The delete request with the watch name (id) to be deleted
|
||||||
|
* @return The response containing the DeleteResponse for this action
|
||||||
|
*/
|
||||||
|
public ActionFuture<DeleteWatchResponse> deleteWatch(DeleteWatchRequest request) {
|
||||||
|
return client.execute(DeleteWatchAction.INSTANCE, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a request builder to build a request to put an watch
|
||||||
|
*
|
||||||
|
* @param watchName The name of the watch to put
|
||||||
|
* @return The builder to create the watch
|
||||||
|
*/
|
||||||
|
public PutWatchRequestBuilder preparePutWatch(String watchName) {
|
||||||
|
return new PutWatchRequestBuilder(client, watchName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a request builder to build a request to put a watch
|
||||||
|
*
|
||||||
|
* @return The builder
|
||||||
|
*/
|
||||||
|
public PutWatchRequestBuilder preparePutWatch() {
|
||||||
|
return new PutWatchRequestBuilder(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the given watch to the watcher
|
||||||
|
*
|
||||||
|
* @param request The request containing the watch to be added
|
||||||
|
* @param listener The listener for the response containing the IndexResponse for this watch
|
||||||
|
*/
|
||||||
|
public void putWatch(PutWatchRequest request, ActionListener<PutWatchResponse> listener) {
|
||||||
|
client.execute(PutWatchAction.INSTANCE, request, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new watch
|
||||||
|
*
|
||||||
|
* @param request The request containing the watch to be added
|
||||||
|
* @return The response containing the IndexResponse for this watch
|
||||||
|
*/
|
||||||
|
public ActionFuture<PutWatchResponse> putWatch(PutWatchRequest request) {
|
||||||
|
return client.execute(PutWatchAction.INSTANCE, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the watcher stats
|
||||||
|
*
|
||||||
|
* @param request The request for the watcher stats
|
||||||
|
* @return The response containing the StatsResponse for this action
|
||||||
|
*/
|
||||||
|
public ActionFuture<WatcherStatsResponse> watcherStats(WatcherStatsRequest request) {
|
||||||
|
return client.execute(WatcherStatsAction.INSTANCE, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a request builder to build a request to get the watcher stats
|
||||||
|
*
|
||||||
|
* @return The builder get the watcher stats
|
||||||
|
*/
|
||||||
|
public WatcherStatsRequestBuilder prepareWatcherStats() {
|
||||||
|
return new WatcherStatsRequestBuilder(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the watcher stats
|
||||||
|
*
|
||||||
|
* @param request The request for the watcher stats
|
||||||
|
* @param listener The listener for the response containing the WatcherStatsResponse
|
||||||
|
*/
|
||||||
|
public void watcherStats(WatcherStatsRequest request, ActionListener<WatcherStatsResponse> listener) {
|
||||||
|
client.execute(WatcherStatsAction.INSTANCE, request, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a request builder to ack a watch by name (id)
|
||||||
|
*
|
||||||
|
* @param watcherName the name (id) of the watch
|
||||||
|
* @return The request builder
|
||||||
|
*/
|
||||||
|
public AckWatchRequestBuilder prepareAckWatch(String watcherName) {
|
||||||
|
return new AckWatchRequestBuilder(client, watcherName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a request builder that acks an watch
|
||||||
|
*
|
||||||
|
* @return The request builder
|
||||||
|
*/
|
||||||
|
public AckWatchRequestBuilder prepareAckWatch() {
|
||||||
|
return new AckWatchRequestBuilder(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ack a watch
|
||||||
|
*
|
||||||
|
* @param request The ack request with the watch name (id) to be acked
|
||||||
|
* @param listener The listener for the ack watch response
|
||||||
|
*/
|
||||||
|
public void ackWatch(AckWatchRequest request, ActionListener<AckWatchResponse> listener) {
|
||||||
|
client.execute(AckWatchAction.INSTANCE, request, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acks an watch
|
||||||
|
*
|
||||||
|
* @param request The ack request with the watch name (id) to be acked
|
||||||
|
* @return The AckWatchResponse
|
||||||
|
*/
|
||||||
|
public ActionFuture<AckWatchResponse> ackWatch(AckWatchRequest request) {
|
||||||
|
return client.execute(AckWatchAction.INSTANCE, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a watch service request.
|
||||||
|
*/
|
||||||
|
public WatcherServiceRequestBuilder prepareWatchService() {
|
||||||
|
return new WatcherServiceRequestBuilder(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an watcher service request to either start, stop or restart the service.
|
||||||
|
*/
|
||||||
|
public void watcherService(WatcherServiceRequest request, ActionListener<WatcherServiceResponse> listener) {
|
||||||
|
client.execute(WatcherServiceAction.INSTANCE, request, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an watcher service request to either start, stop or restart the service.
|
||||||
|
*/
|
||||||
|
public ActionFuture<WatcherServiceResponse> watcherService(WatcherServiceRequest request) {
|
||||||
|
return client.execute(WatcherServiceAction.INSTANCE, request);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,17 +3,17 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.client;
|
package org.elasticsearch.watcher.client;
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
import org.elasticsearch.common.inject.AbstractModule;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class AlertsClientModule extends AbstractModule {
|
public class WatcherClientModule extends AbstractModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(AlertsClient.class).asEagerSingleton();
|
bind(WatcherClient.class).asEagerSingleton();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,9 +3,9 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.condition;
|
package org.elasticsearch.watcher.condition;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.ExecutionContext;
|
import org.elasticsearch.watcher.watch.WatchExecutionContext;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
|
@ -34,7 +34,7 @@ public abstract class Condition<R extends Condition.Result> implements ToXConten
|
||||||
/**
|
/**
|
||||||
* Executes this condition
|
* Executes this condition
|
||||||
*/
|
*/
|
||||||
public abstract R execute(ExecutionContext ctx) throws IOException;
|
public abstract R execute(WatchExecutionContext ctx) throws IOException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -3,10 +3,10 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.condition;
|
package org.elasticsearch.watcher.condition;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.condition.script.ScriptCondition;
|
import org.elasticsearch.watcher.condition.script.ScriptCondition;
|
||||||
import org.elasticsearch.alerts.condition.simple.AlwaysTrueCondition;
|
import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
|
@ -3,14 +3,14 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.condition;
|
package org.elasticsearch.watcher.condition;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.AlertsException;
|
import org.elasticsearch.watcher.WatcherException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ConditionException extends AlertsException {
|
public class ConditionException extends WatcherException {
|
||||||
|
|
||||||
public ConditionException(String msg) {
|
public ConditionException(String msg) {
|
||||||
super(msg);
|
super(msg);
|
|
@ -3,11 +3,11 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.condition;
|
package org.elasticsearch.watcher.condition;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.condition.script.ScriptCondition;
|
import org.elasticsearch.watcher.condition.script.ScriptCondition;
|
||||||
import org.elasticsearch.alerts.condition.simple.AlwaysFalseCondition;
|
import org.elasticsearch.watcher.condition.simple.AlwaysFalseCondition;
|
||||||
import org.elasticsearch.alerts.condition.simple.AlwaysTrueCondition;
|
import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition;
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
import org.elasticsearch.common.inject.AbstractModule;
|
||||||
import org.elasticsearch.common.inject.multibindings.MapBinder;
|
import org.elasticsearch.common.inject.multibindings.MapBinder;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.condition;
|
package org.elasticsearch.watcher.condition;
|
||||||
|
|
||||||
import org.elasticsearch.common.collect.ImmutableMap;
|
import org.elasticsearch.common.collect.ImmutableMap;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
|
@ -3,15 +3,15 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.condition.script;
|
package org.elasticsearch.watcher.condition.script;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.AlertsSettingsException;
|
import org.elasticsearch.watcher.WatcherSettingsException;
|
||||||
import org.elasticsearch.alerts.ExecutionContext;
|
import org.elasticsearch.watcher.watch.WatchExecutionContext;
|
||||||
import org.elasticsearch.alerts.condition.Condition;
|
import org.elasticsearch.watcher.condition.Condition;
|
||||||
import org.elasticsearch.alerts.condition.ConditionException;
|
import org.elasticsearch.watcher.condition.ConditionException;
|
||||||
import org.elasticsearch.alerts.support.Script;
|
import org.elasticsearch.watcher.support.Script;
|
||||||
import org.elasticsearch.alerts.support.Variables;
|
import org.elasticsearch.watcher.support.Variables;
|
||||||
import org.elasticsearch.alerts.support.init.proxy.ScriptServiceProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
|
||||||
import org.elasticsearch.common.collect.ImmutableMap;
|
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;
|
||||||
|
@ -52,7 +52,7 @@ public class ScriptCondition extends Condition<ScriptCondition.Result> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result execute(ExecutionContext ctx) throws IOException {
|
public Result execute(WatchExecutionContext ctx) throws IOException {
|
||||||
ImmutableMap<String, Object> model = ImmutableMap.<String, Object>builder()
|
ImmutableMap<String, Object> model = ImmutableMap.<String, Object>builder()
|
||||||
.putAll(script.params())
|
.putAll(script.params())
|
||||||
.putAll(Variables.createCtxModel(ctx, ctx.payload()))
|
.putAll(Variables.createCtxModel(ctx, ctx.payload()))
|
||||||
|
@ -108,7 +108,7 @@ public class ScriptCondition extends Condition<ScriptCondition.Result> {
|
||||||
Script script = Script.parse(parser);
|
Script script = Script.parse(parser);
|
||||||
return new ScriptCondition(logger, scriptService, script);
|
return new ScriptCondition(logger, scriptService, script);
|
||||||
} catch (Script.ParseException pe) {
|
} catch (Script.ParseException pe) {
|
||||||
throw new AlertsSettingsException("could not parse [script] condition", pe);
|
throw new WatcherSettingsException("could not parse [script] condition", pe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,15 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.condition.simple;
|
package org.elasticsearch.watcher.condition.simple;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.ExecutionContext;
|
import org.elasticsearch.watcher.watch.WatchExecutionContext;
|
||||||
import org.elasticsearch.alerts.condition.Condition;
|
import org.elasticsearch.watcher.condition.Condition;
|
||||||
import org.elasticsearch.alerts.condition.ConditionException;
|
import org.elasticsearch.watcher.condition.ConditionException;
|
||||||
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;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
|
||||||
|
@ -43,7 +42,7 @@ public class AlwaysFalseCondition extends Condition<Condition.Result> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result execute(ExecutionContext ctx) throws IOException {
|
public Result execute(WatchExecutionContext ctx) throws IOException {
|
||||||
return RESULT;
|
return RESULT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.condition.simple;
|
package org.elasticsearch.watcher.condition.simple;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.ExecutionContext;
|
import org.elasticsearch.watcher.watch.WatchExecutionContext;
|
||||||
import org.elasticsearch.alerts.condition.Condition;
|
import org.elasticsearch.watcher.condition.Condition;
|
||||||
import org.elasticsearch.alerts.condition.ConditionException;
|
import org.elasticsearch.watcher.condition.ConditionException;
|
||||||
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;
|
||||||
|
@ -41,7 +41,7 @@ public class AlwaysTrueCondition extends Condition<Condition.Result> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result execute(ExecutionContext ctx) throws IOException {
|
public Result execute(WatchExecutionContext ctx) throws IOException {
|
||||||
return RESULT;
|
return RESULT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.history;
|
package org.elasticsearch.watcher.history;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.AlertsException;
|
import org.elasticsearch.watcher.WatcherException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class HistoryException extends AlertsException {
|
public class HistoryException extends WatcherException {
|
||||||
|
|
||||||
public HistoryException(String msg) {
|
public HistoryException(String msg) {
|
||||||
super(msg);
|
super(msg);
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.history;
|
package org.elasticsearch.watcher.history;
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
import org.elasticsearch.common.inject.AbstractModule;
|
||||||
|
|
||||||
|
@ -11,22 +11,22 @@ import org.elasticsearch.common.inject.AbstractModule;
|
||||||
*/
|
*/
|
||||||
public class HistoryModule extends AbstractModule {
|
public class HistoryModule extends AbstractModule {
|
||||||
|
|
||||||
private final Class<? extends AlertsExecutor> executorClass;
|
private final Class<? extends WatchExecutor> executorClass;
|
||||||
|
|
||||||
public HistoryModule() {
|
public HistoryModule() {
|
||||||
this(InternalAlertsExecutor.class);
|
this(InternalWatchExecutor.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HistoryModule(Class<? extends AlertsExecutor> executorClass) {
|
protected HistoryModule(Class<? extends WatchExecutor> executorClass) {
|
||||||
this.executorClass = executorClass;
|
this.executorClass = executorClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(FiredAlert.Parser.class).asEagerSingleton();
|
bind(WatchRecord.Parser.class).asEagerSingleton();
|
||||||
bind(HistoryStore.class).asEagerSingleton();
|
bind(HistoryStore.class).asEagerSingleton();
|
||||||
bind(HistoryService.class).asEagerSingleton();
|
bind(HistoryService.class).asEagerSingleton();
|
||||||
bind(executorClass).asEagerSingleton();
|
bind(executorClass).asEagerSingleton();
|
||||||
bind(AlertsExecutor.class).to(executorClass);
|
bind(WatchExecutor.class).to(executorClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,18 +3,17 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.history;
|
package org.elasticsearch.watcher.history;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchIllegalStateException;
|
import org.elasticsearch.ElasticsearchIllegalStateException;
|
||||||
import org.elasticsearch.alerts.*;
|
import org.elasticsearch.watcher.actions.Action;
|
||||||
import org.elasticsearch.alerts.actions.Action;
|
import org.elasticsearch.watcher.condition.Condition;
|
||||||
import org.elasticsearch.alerts.condition.Condition;
|
import org.elasticsearch.watcher.input.Input;
|
||||||
import org.elasticsearch.alerts.input.Input;
|
import org.elasticsearch.watcher.scheduler.Scheduler;
|
||||||
import org.elasticsearch.alerts.scheduler.Scheduler;
|
import org.elasticsearch.watcher.support.Callback;
|
||||||
import org.elasticsearch.alerts.support.Callback;
|
import org.elasticsearch.watcher.support.clock.Clock;
|
||||||
import org.elasticsearch.alerts.support.clock.Clock;
|
import org.elasticsearch.watcher.throttle.Throttler;
|
||||||
import org.elasticsearch.alerts.throttle.Throttler;
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
import org.elasticsearch.alerts.transform.Transform;
|
|
||||||
import org.elasticsearch.cluster.ClusterChangedEvent;
|
import org.elasticsearch.cluster.ClusterChangedEvent;
|
||||||
import org.elasticsearch.cluster.ClusterService;
|
import org.elasticsearch.cluster.ClusterService;
|
||||||
import org.elasticsearch.cluster.ClusterState;
|
import org.elasticsearch.cluster.ClusterState;
|
||||||
|
@ -24,9 +23,11 @@ import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.joda.time.DateTime;
|
import org.elasticsearch.common.joda.time.DateTime;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException;
|
import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException;
|
||||||
|
import org.elasticsearch.watcher.watch.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
@ -36,24 +37,24 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||||
public class HistoryService extends AbstractComponent {
|
public class HistoryService extends AbstractComponent {
|
||||||
|
|
||||||
private final HistoryStore historyStore;
|
private final HistoryStore historyStore;
|
||||||
private final AlertsExecutor executor;
|
private final WatchExecutor executor;
|
||||||
private final AlertsStore alertsStore;
|
private final WatchStore watchStore;
|
||||||
private final ClusterService clusterService;
|
private final ClusterService clusterService;
|
||||||
private final AlertLockService alertLockService;
|
private final WatchLockService watchLockService;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
|
|
||||||
private final AtomicBoolean started = new AtomicBoolean(false);
|
private final AtomicBoolean started = new AtomicBoolean(false);
|
||||||
private final AtomicInteger initializationRetries = new AtomicInteger();
|
private final AtomicInteger initializationRetries = new AtomicInteger();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public HistoryService(Settings settings, HistoryStore historyStore, AlertsExecutor executor,
|
public HistoryService(Settings settings, HistoryStore historyStore, WatchExecutor executor,
|
||||||
AlertsStore alertsStore, AlertLockService alertLockService, Scheduler scheduler,
|
WatchStore watchStore, WatchLockService watchLockService, Scheduler scheduler,
|
||||||
ClusterService clusterService, Clock clock) {
|
ClusterService clusterService, Clock clock) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.historyStore = historyStore;
|
this.historyStore = historyStore;
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
this.alertsStore = alertsStore;
|
this.watchStore = watchStore;
|
||||||
this.alertLockService = alertLockService;
|
this.watchLockService = watchLockService;
|
||||||
this.clusterService = clusterService;
|
this.clusterService = clusterService;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
scheduler.addListener(new SchedulerListener());
|
scheduler.addListener(new SchedulerListener());
|
||||||
|
@ -66,14 +67,14 @@ public class HistoryService extends AbstractComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert executor.queue().isEmpty() : "queue should be empty, but contains " + executor.queue().size() + " elements.";
|
assert executor.queue().isEmpty() : "queue should be empty, but contains " + executor.queue().size() + " elements.";
|
||||||
HistoryStore.LoadResult loadResult = historyStore.loadFiredAlerts(state, FiredAlert.State.AWAITS_EXECUTION);
|
Collection<WatchRecord> records = historyStore.loadRecords(state, WatchRecord.State.AWAITS_EXECUTION);
|
||||||
if (!loadResult.succeeded()) {
|
if (records == null) {
|
||||||
retry(callback);
|
retry(callback);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (started.compareAndSet(false, true)) {
|
if (started.compareAndSet(false, true)) {
|
||||||
logger.debug("starting history service");
|
logger.debug("starting history service");
|
||||||
executePreviouslyFiredAlerts(loadResult);
|
executeRecords(records);
|
||||||
logger.debug("started history service");
|
logger.debug("started history service");
|
||||||
}
|
}
|
||||||
callback.onSuccess(state);
|
callback.onSuccess(state);
|
||||||
|
@ -105,55 +106,54 @@ public class HistoryService extends AbstractComponent {
|
||||||
return executor.largestPoolSize();
|
return executor.largestPoolSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void fire(Alert alert, DateTime scheduledFireTime, DateTime fireTime) throws HistoryException {
|
void execute(Watch watch, DateTime scheduledFireTime, DateTime fireTime) throws HistoryException {
|
||||||
if (!started.get()) {
|
if (!started.get()) {
|
||||||
throw new ElasticsearchIllegalStateException("not started");
|
throw new ElasticsearchIllegalStateException("not started");
|
||||||
}
|
}
|
||||||
FiredAlert firedAlert = new FiredAlert(alert, scheduledFireTime, fireTime);
|
WatchRecord watchRecord = new WatchRecord(watch, scheduledFireTime, fireTime);
|
||||||
logger.debug("adding fired alert [{}]", alert.name());
|
logger.debug("saving watch record [{}]", watch.name());
|
||||||
historyStore.put(firedAlert);
|
historyStore.put(watchRecord);
|
||||||
executeAsync(firedAlert, alert);
|
executeAsync(watchRecord, watch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The execution of an alert is split into operations, a schedule part which just makes sure that store the fact an alert
|
The execution of an watch is split into two phases:
|
||||||
has fired and an execute part which actually executed the alert.
|
1. the trigger part which just makes sure to store the associated watch record in the history
|
||||||
|
2. the actual processing of the watch
|
||||||
|
|
||||||
The reason this is split into two operations is that we don't want to lose the fact an alert has fired. If we
|
The reason this split is that we don't want to lose the fact watch was triggered. This way, even if the
|
||||||
would not split the execution of an alert and many alerts fire in a small window of time then it can happen that
|
thread pool that executes the watches is completely busy, we don't lose the fact that the watch was
|
||||||
thread pool that receives fired jobs from the quartz scheduler is going to reject jobs and then we would never
|
triggered (it'll have its history record)
|
||||||
know about jobs that have fired. By splitting the execution of fired jobs into two operations we lower the chance
|
|
||||||
we lose fired jobs signficantly.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void executeAsync(FiredAlert firedAlert, Alert alert) {
|
void executeAsync(WatchRecord watchRecord, Watch watch) {
|
||||||
try {
|
try {
|
||||||
executor.execute(new AlertExecutionTask(firedAlert, alert));
|
executor.execute(new WatchExecutionTask(watchRecord, watch));
|
||||||
} catch (EsRejectedExecutionException e) {
|
} catch (EsRejectedExecutionException e) {
|
||||||
logger.debug("[{}] failed to execute fired alert", firedAlert.name());
|
logger.debug("failed to execute triggered watch [{}]", watchRecord.name());
|
||||||
firedAlert.update(FiredAlert.State.FAILED, "failed to run fired alert due to thread pool capacity");
|
watchRecord.update(WatchRecord.State.FAILED, "failed to run triggered watch [" + watchRecord.name() + "] due to thread pool capacity");
|
||||||
historyStore.update(firedAlert);
|
historyStore.update(watchRecord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AlertExecution execute(ExecutionContext ctx) throws IOException {
|
WatchExecution execute(WatchExecutionContext ctx) throws IOException {
|
||||||
Alert alert = ctx.alert();
|
Watch watch = ctx.watch();
|
||||||
Input.Result inputResult = alert.input().execute(ctx);
|
Input.Result inputResult = watch.input().execute(ctx);
|
||||||
ctx.onInputResult(inputResult);
|
ctx.onInputResult(inputResult);
|
||||||
Condition.Result conditionResult = alert.condition().execute(ctx);
|
Condition.Result conditionResult = watch.condition().execute(ctx);
|
||||||
ctx.onConditionResult(conditionResult);
|
ctx.onConditionResult(conditionResult);
|
||||||
|
|
||||||
if (conditionResult.met()) {
|
if (conditionResult.met()) {
|
||||||
Throttler.Result throttleResult = alert.throttler().throttle(ctx);
|
Throttler.Result throttleResult = watch.throttler().throttle(ctx);
|
||||||
ctx.onThrottleResult(throttleResult);
|
ctx.onThrottleResult(throttleResult);
|
||||||
|
|
||||||
if (!throttleResult.throttle()) {
|
if (!throttleResult.throttle()) {
|
||||||
Transform transform = alert.transform();
|
Transform transform = watch.transform();
|
||||||
if (transform != null) {
|
if (transform != null) {
|
||||||
Transform.Result result = alert.transform().apply(ctx, inputResult.payload());
|
Transform.Result result = watch.transform().apply(ctx, inputResult.payload());
|
||||||
ctx.onTransformResult(result);
|
ctx.onTransformResult(result);
|
||||||
}
|
}
|
||||||
for (Action action : alert.actions()) {
|
for (Action action : watch.actions()) {
|
||||||
Action.Result actionResult = action.execute(ctx);
|
Action.Result actionResult = action.execute(ctx);
|
||||||
ctx.onActionResult(actionResult);
|
ctx.onActionResult(actionResult);
|
||||||
}
|
}
|
||||||
|
@ -162,20 +162,19 @@ public class HistoryService extends AbstractComponent {
|
||||||
return ctx.finish();
|
return ctx.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
void executePreviouslyFiredAlerts(HistoryStore.LoadResult loadResult) {
|
void executeRecords(Collection<WatchRecord> records) {
|
||||||
if (loadResult != null) {
|
assert records != null;
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
for (FiredAlert firedAlert : loadResult) {
|
for (WatchRecord record : records) {
|
||||||
Alert alert = alertsStore.getAlert(firedAlert.name());
|
Watch watch = watchStore.get(record.name());
|
||||||
if (alert == null) {
|
if (watch == null) {
|
||||||
logger.warn("unable to find alert [{}] in alert store, perhaps it has been deleted. skipping...", firedAlert.name());
|
logger.warn("unable to find watch [{}] in watch store. perhaps it has been deleted. skipping...", record.name());
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
executeAsync(firedAlert, alert);
|
|
||||||
counter++;
|
|
||||||
}
|
}
|
||||||
logger.debug("executed [{}] not executed previous fired alerts from the alert history index ", counter);
|
executeAsync(record, watch);
|
||||||
|
counter++;
|
||||||
}
|
}
|
||||||
|
logger.debug("executed [{}] watches from the watch history", counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void retry(final Callback<ClusterState> callback) {
|
private void retry(final Callback<ClusterState> callback) {
|
||||||
|
@ -204,42 +203,42 @@ public class HistoryService extends AbstractComponent {
|
||||||
clusterService.add(clusterStateListener);
|
clusterService.add(clusterStateListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class AlertExecutionTask implements Runnable {
|
private final class WatchExecutionTask implements Runnable {
|
||||||
|
|
||||||
private final FiredAlert firedAlert;
|
private final WatchRecord watchRecord;
|
||||||
private final Alert alert;
|
private final Watch watch;
|
||||||
|
|
||||||
private AlertExecutionTask(FiredAlert firedAlert, Alert alert) {
|
private WatchExecutionTask(WatchRecord watchRecord, Watch watch) {
|
||||||
this.firedAlert = firedAlert;
|
this.watchRecord = watchRecord;
|
||||||
this.alert = alert;
|
this.watch = watch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!started.get()) {
|
if (!started.get()) {
|
||||||
logger.debug("can't run alert execution, because history service is not started, ignoring it...");
|
logger.debug("can't initiate watch execution as history service is not started, ignoring it...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AlertLockService.Lock lock = alertLockService.acquire(alert.name());
|
WatchLockService.Lock lock = watchLockService.acquire(watch.name());
|
||||||
try {
|
try {
|
||||||
firedAlert.update(FiredAlert.State.CHECKING, null);
|
watchRecord.update(WatchRecord.State.CHECKING, null);
|
||||||
logger.debug("checking alert [{}]", firedAlert.name());
|
logger.debug("checking watch [{}]", watchRecord.name());
|
||||||
ExecutionContext ctx = new ExecutionContext(firedAlert.id(), alert, clock.now(), firedAlert.fireTime(), firedAlert.scheduledTime());
|
WatchExecutionContext ctx = new WatchExecutionContext(watchRecord.id(), watch, clock.now(), watchRecord.fireTime(), watchRecord.scheduledTime());
|
||||||
AlertExecution alertExecution = execute(ctx);
|
WatchExecution execution = execute(ctx);
|
||||||
firedAlert.update(alertExecution);
|
watchRecord.seal(execution);
|
||||||
historyStore.update(firedAlert);
|
historyStore.update(watchRecord);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (started()) {
|
if (started()) {
|
||||||
logger.warn("failed to run alert [{}]", e, firedAlert.name());
|
logger.warn("failed to execute watch [{}]", e, watchRecord.name());
|
||||||
try {
|
try {
|
||||||
firedAlert.update(FiredAlert.State.FAILED, e.getMessage());
|
watchRecord.update(WatchRecord.State.FAILED, e.getMessage());
|
||||||
historyStore.update(firedAlert);
|
historyStore.update(watchRecord);
|
||||||
|
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
logger.error("failed to update fired alert [{}] with the error message", e2, firedAlert);
|
logger.error("failed to update watch record [{}] failure [{}]", e2, watchRecord, e.getMessage());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.debug("failed to execute fired alert [{}] after shutdown", e, firedAlert);
|
logger.debug("failed to execute watch [{}] after shutdown", e, watchRecord);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
lock.release();
|
lock.release();
|
||||||
|
@ -254,15 +253,15 @@ public class HistoryService extends AbstractComponent {
|
||||||
if (!started.get()) {
|
if (!started.get()) {
|
||||||
throw new ElasticsearchIllegalStateException("not started");
|
throw new ElasticsearchIllegalStateException("not started");
|
||||||
}
|
}
|
||||||
Alert alert = alertsStore.getAlert(name);
|
Watch watch = watchStore.get(name);
|
||||||
if (alert == null) {
|
if (watch == null) {
|
||||||
logger.warn("unable to find [{}] in the alert store, perhaps it has been deleted", name);
|
logger.warn("unable to find watch [{}] in the watch store, perhaps it has been deleted", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
HistoryService.this.fire(alert, scheduledFireTime, fireTime);
|
HistoryService.this.execute(watch, scheduledFireTime, fireTime);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("failed to fire alert [{}]", e, name);
|
logger.error("failed to execute watch [{}]", e, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,166 @@
|
||||||
|
/*
|
||||||
|
* 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.history;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
|
||||||
|
import org.elasticsearch.action.admin.indices.refresh.RefreshResponse;
|
||||||
|
import org.elasticsearch.action.index.IndexRequest;
|
||||||
|
import org.elasticsearch.action.index.IndexResponse;
|
||||||
|
import org.elasticsearch.action.search.*;
|
||||||
|
import org.elasticsearch.action.support.IndicesOptions;
|
||||||
|
import org.elasticsearch.watcher.support.TemplateUtils;
|
||||||
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
|
import org.elasticsearch.cluster.ClusterState;
|
||||||
|
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||||
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
|
import org.elasticsearch.common.component.AbstractComponent;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.joda.time.DateTime;
|
||||||
|
import org.elasticsearch.common.joda.time.format.DateTimeFormat;
|
||||||
|
import org.elasticsearch.common.joda.time.format.DateTimeFormatter;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
|
import org.elasticsearch.index.query.QueryBuilders;
|
||||||
|
import org.elasticsearch.search.SearchHit;
|
||||||
|
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public class HistoryStore extends AbstractComponent {
|
||||||
|
|
||||||
|
public static final String INDEX_PREFIX = ".watch_history_";
|
||||||
|
public static final String DOC_TYPE = "watch_record";
|
||||||
|
public static final String INDEX_TEMPLATE_NAME = "watch_history";
|
||||||
|
|
||||||
|
static final DateTimeFormatter indexTimeFormat = DateTimeFormat.forPattern("YYYY-MM-dd");
|
||||||
|
|
||||||
|
private final ClientProxy client;
|
||||||
|
private final TemplateUtils templateUtils;
|
||||||
|
private final int scrollSize;
|
||||||
|
private final TimeValue scrollTimeout;
|
||||||
|
private final WatchRecord.Parser recordParser;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public HistoryStore(Settings settings, ClientProxy client, TemplateUtils templateUtils, WatchRecord.Parser recordParser) {
|
||||||
|
super(settings);
|
||||||
|
this.client = client;
|
||||||
|
this.templateUtils = templateUtils;
|
||||||
|
this.recordParser = recordParser;
|
||||||
|
this.scrollTimeout = componentSettings.getAsTime("scroll.timeout", TimeValue.timeValueSeconds(30));
|
||||||
|
this.scrollSize = componentSettings.getAsInt("scroll.size", 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(WatchRecord watchRecord) throws HistoryException {
|
||||||
|
String index = getHistoryIndexNameForTime(watchRecord.scheduledTime());
|
||||||
|
try {
|
||||||
|
IndexResponse response = client.prepareIndex(index, DOC_TYPE, watchRecord.id())
|
||||||
|
.setSource(XContentFactory.jsonBuilder().value(watchRecord))
|
||||||
|
.setOpType(IndexRequest.OpType.CREATE)
|
||||||
|
.get();
|
||||||
|
watchRecord.version(response.getVersion());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new HistoryException("failed to persist watch record [" + watchRecord + "]", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(WatchRecord watchRecord) throws HistoryException {
|
||||||
|
logger.debug("updating watch record [{}]...", watchRecord);
|
||||||
|
try {
|
||||||
|
BytesReference bytes = XContentFactory.jsonBuilder().value(watchRecord).bytes();
|
||||||
|
IndexResponse response = client.prepareIndex(getHistoryIndexNameForTime(watchRecord.scheduledTime()), DOC_TYPE, watchRecord.id())
|
||||||
|
.setSource(bytes)
|
||||||
|
.setVersion(watchRecord.version())
|
||||||
|
.get();
|
||||||
|
watchRecord.version(response.getVersion());
|
||||||
|
logger.debug("successfully updated watch record [{}]", watchRecord);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new HistoryException("failed to update watch record [" + watchRecord + "]", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tries to load all watch records that await execution. If for some reason the records could not be
|
||||||
|
* loaded (e.g. the not all primary shards of the history index are active), returns {@code null}.
|
||||||
|
*/
|
||||||
|
Collection<WatchRecord> loadRecords(ClusterState state, WatchRecord.State recordState) {
|
||||||
|
String[] indices = state.metaData().concreteIndices(IndicesOptions.lenientExpandOpen(), INDEX_PREFIX + "*");
|
||||||
|
if (indices.length == 0) {
|
||||||
|
logger.debug("No .watch_history indices found. skipping loading awaiting watch records");
|
||||||
|
templateUtils.ensureIndexTemplateIsLoaded(state, INDEX_TEMPLATE_NAME);
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
int numPrimaryShards = 0;
|
||||||
|
for (String index : indices) {
|
||||||
|
IndexMetaData indexMetaData = state.getMetaData().index(index);
|
||||||
|
if (indexMetaData != null) {
|
||||||
|
if (!state.routingTable().index(index).allPrimaryShardsActive()) {
|
||||||
|
logger.debug("Not all primary shards of the [{}] index are started. Schedule to retry loading awaiting watch records..", index);
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
numPrimaryShards += indexMetaData.numberOfShards();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshResponse refreshResponse = client.refresh(new RefreshRequest(INDEX_PREFIX + "*"));
|
||||||
|
if (refreshResponse.getSuccessfulShards() < numPrimaryShards) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchRequest searchRequest = createScanSearchRequest(recordState);
|
||||||
|
SearchResponse response = client.search(searchRequest);
|
||||||
|
List<WatchRecord> records = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
if (response.getTotalShards() != response.getSuccessfulShards()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.getHits().getTotalHits() > 0) {
|
||||||
|
response = client.searchScroll(response.getScrollId(), scrollTimeout);
|
||||||
|
while (response.getHits().hits().length != 0) {
|
||||||
|
for (SearchHit sh : response.getHits()) {
|
||||||
|
String historyId = sh.getId();
|
||||||
|
WatchRecord record = recordParser.parse(sh.getSourceRef(), historyId, sh.version());
|
||||||
|
assert record.state() == recordState;
|
||||||
|
logger.debug("loaded watch record [{}/{}/{}]", sh.index(), sh.type(), sh.id());
|
||||||
|
records.add(record);
|
||||||
|
}
|
||||||
|
response = client.searchScroll(response.getScrollId(), scrollTimeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
client.clearScroll(response.getScrollId());
|
||||||
|
}
|
||||||
|
templateUtils.ensureIndexTemplateIsLoaded(state, INDEX_TEMPLATE_NAME);
|
||||||
|
return records;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the correct history index name for a given time
|
||||||
|
*/
|
||||||
|
public static String getHistoryIndexNameForTime(DateTime time) {
|
||||||
|
return INDEX_PREFIX + indexTimeFormat.print(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SearchRequest createScanSearchRequest(WatchRecord.State recordState) {
|
||||||
|
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
|
||||||
|
.query(QueryBuilders.termQuery(WatchRecord.Parser.STATE_FIELD.getPreferredName(), recordState.id()))
|
||||||
|
.size(scrollSize)
|
||||||
|
.version(true);
|
||||||
|
|
||||||
|
SearchRequest searchRequest = new SearchRequest(INDEX_PREFIX + "*");
|
||||||
|
searchRequest.source(sourceBuilder);
|
||||||
|
searchRequest.searchType(SearchType.SCAN);
|
||||||
|
searchRequest.types(DOC_TYPE);
|
||||||
|
searchRequest.scroll(scrollTimeout);
|
||||||
|
searchRequest.preference("_primary");
|
||||||
|
return searchRequest;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,9 +3,9 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.history;
|
package org.elasticsearch.watcher.history;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.AlertsPlugin;
|
import org.elasticsearch.watcher.WatcherPlugin;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor;
|
import org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
|
@ -15,12 +15,12 @@ import java.util.concurrent.BlockingQueue;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class InternalAlertsExecutor implements AlertsExecutor {
|
public class InternalWatchExecutor implements WatchExecutor {
|
||||||
|
|
||||||
private final ThreadPool threadPool;
|
private final ThreadPool threadPool;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public InternalAlertsExecutor(ThreadPool threadPool) {
|
public InternalWatchExecutor(ThreadPool threadPool) {
|
||||||
this.threadPool = threadPool;
|
this.threadPool = threadPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,6 @@ public class InternalAlertsExecutor implements AlertsExecutor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private EsThreadPoolExecutor executor() {
|
private EsThreadPoolExecutor executor() {
|
||||||
return (EsThreadPoolExecutor) threadPool.executor(AlertsPlugin.NAME);
|
return (EsThreadPoolExecutor) threadPool.executor(WatcherPlugin.NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,14 +3,14 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.history;
|
package org.elasticsearch.watcher.history;
|
||||||
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface AlertsExecutor {
|
public interface WatchExecutor {
|
||||||
|
|
||||||
BlockingQueue queue();
|
BlockingQueue queue();
|
||||||
|
|
|
@ -3,19 +3,19 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.history;
|
package org.elasticsearch.watcher.history;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.alerts.Alert;
|
import org.elasticsearch.watcher.watch.Watch;
|
||||||
import org.elasticsearch.alerts.AlertExecution;
|
import org.elasticsearch.watcher.watch.WatchExecution;
|
||||||
import org.elasticsearch.alerts.AlertsException;
|
import org.elasticsearch.watcher.WatcherException;
|
||||||
import org.elasticsearch.alerts.AlertsSettingsException;
|
import org.elasticsearch.watcher.WatcherSettingsException;
|
||||||
import org.elasticsearch.alerts.actions.ActionRegistry;
|
import org.elasticsearch.watcher.actions.ActionRegistry;
|
||||||
import org.elasticsearch.alerts.condition.Condition;
|
import org.elasticsearch.watcher.condition.Condition;
|
||||||
import org.elasticsearch.alerts.condition.ConditionRegistry;
|
import org.elasticsearch.watcher.condition.ConditionRegistry;
|
||||||
import org.elasticsearch.alerts.input.Input;
|
import org.elasticsearch.watcher.input.Input;
|
||||||
import org.elasticsearch.alerts.input.InputRegistry;
|
import org.elasticsearch.watcher.input.InputRegistry;
|
||||||
import org.elasticsearch.alerts.transform.TransformRegistry;
|
import org.elasticsearch.watcher.transform.TransformRegistry;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
|
@ -33,7 +33,7 @@ import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class FiredAlert implements ToXContent {
|
public class WatchRecord implements ToXContent {
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
private String name;
|
private String name;
|
||||||
|
@ -42,7 +42,7 @@ public class FiredAlert implements ToXContent {
|
||||||
private Input input;
|
private Input input;
|
||||||
private Condition condition;
|
private Condition condition;
|
||||||
private State state;
|
private State state;
|
||||||
private AlertExecution execution;
|
private WatchExecution execution;
|
||||||
|
|
||||||
private @Nullable String message;
|
private @Nullable String message;
|
||||||
private @Nullable Map<String,Object> metadata;
|
private @Nullable Map<String,Object> metadata;
|
||||||
|
@ -52,18 +52,18 @@ public class FiredAlert implements ToXContent {
|
||||||
|
|
||||||
private final AtomicBoolean sealed = new AtomicBoolean(false);
|
private final AtomicBoolean sealed = new AtomicBoolean(false);
|
||||||
|
|
||||||
FiredAlert() {
|
WatchRecord() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public FiredAlert(Alert alert, DateTime scheduledTime, DateTime fireTime) {
|
public WatchRecord(Watch watch, DateTime scheduledTime, DateTime fireTime) {
|
||||||
this.id = alert.name() + "#" + scheduledTime.toDateTimeISO();
|
this.id = watch.name() + "#" + scheduledTime.toDateTimeISO();
|
||||||
this.name = alert.name();
|
this.name = watch.name();
|
||||||
this.fireTime = fireTime;
|
this.fireTime = fireTime;
|
||||||
this.scheduledTime = scheduledTime;
|
this.scheduledTime = scheduledTime;
|
||||||
this.condition = alert.condition();
|
this.condition = watch.condition();
|
||||||
this.input = alert.input();
|
this.input = watch.input();
|
||||||
this.state = State.AWAITS_EXECUTION;
|
this.state = State.AWAITS_EXECUTION;
|
||||||
this.metadata = alert.metadata();
|
this.metadata = watch.metadata();
|
||||||
this.version = 1;
|
this.version = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,8 +114,8 @@ public class FiredAlert implements ToXContent {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(AlertExecution execution) {
|
public void seal(WatchExecution execution) {
|
||||||
assert sealed.compareAndSet(false, true) : "sealing an fired alert should only be done once";
|
assert sealed.compareAndSet(false, true) : "sealing a watch record should only be done once";
|
||||||
this.execution = execution;
|
this.execution = execution;
|
||||||
if (!execution.conditionResult().met()) {
|
if (!execution.conditionResult().met()) {
|
||||||
state = State.EXECUTION_NOT_NEEDED;
|
state = State.EXECUTION_NOT_NEEDED;
|
||||||
|
@ -131,10 +131,10 @@ public class FiredAlert implements ToXContent {
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder historyEntry, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder historyEntry, Params params) throws IOException {
|
||||||
historyEntry.startObject();
|
historyEntry.startObject();
|
||||||
historyEntry.field(Parser.ALERT_NAME_FIELD.getPreferredName(), name);
|
historyEntry.field(Parser.WATCH_NAME_FIELD.getPreferredName(), name);
|
||||||
historyEntry.field(Parser.FIRE_TIME_FIELD.getPreferredName(), fireTime.toDateTimeISO());
|
historyEntry.field(Parser.FIRE_TIME_FIELD.getPreferredName(), fireTime.toDateTimeISO());
|
||||||
historyEntry.field(Parser.SCHEDULED_FIRE_TIME_FIELD.getPreferredName(), scheduledTime.toDateTimeISO());
|
historyEntry.field(Parser.SCHEDULED_FIRE_TIME_FIELD.getPreferredName(), scheduledTime.toDateTimeISO());
|
||||||
historyEntry.startObject(Alert.Parser.CONDITION_FIELD.getPreferredName()).field(condition.type(), condition, params).endObject();
|
historyEntry.startObject(Watch.Parser.CONDITION_FIELD.getPreferredName()).field(condition.type(), condition, params).endObject();
|
||||||
historyEntry.field(Parser.STATE_FIELD.getPreferredName(), state.id());
|
historyEntry.field(Parser.STATE_FIELD.getPreferredName(), state.id());
|
||||||
|
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
|
@ -145,7 +145,7 @@ public class FiredAlert implements ToXContent {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (execution != null) {
|
if (execution != null) {
|
||||||
historyEntry.field(Parser.ALERT_EXECUTION_FIELD.getPreferredName(), execution);
|
historyEntry.field(Parser.WATCH_EXECUTION_FIELD.getPreferredName(), execution);
|
||||||
}
|
}
|
||||||
|
|
||||||
historyEntry.endObject();
|
historyEntry.endObject();
|
||||||
|
@ -157,7 +157,7 @@ public class FiredAlert implements ToXContent {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
FiredAlert entry = (FiredAlert) o;
|
WatchRecord entry = (WatchRecord) o;
|
||||||
if (!id.equals(entry.id)) return false;
|
if (!id.equals(entry.id)) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -190,7 +190,7 @@ public class FiredAlert implements ToXContent {
|
||||||
try {
|
try {
|
||||||
return valueOf(id.toUpperCase(Locale.ROOT));
|
return valueOf(id.toUpperCase(Locale.ROOT));
|
||||||
} catch (IllegalArgumentException iae) {
|
} catch (IllegalArgumentException iae) {
|
||||||
throw new AlertsSettingsException("unknown fired alert state [" + id + "]");
|
throw new WatcherSettingsException("unknown watch record state [" + id + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,13 +202,13 @@ public class FiredAlert implements ToXContent {
|
||||||
|
|
||||||
public static class Parser extends AbstractComponent {
|
public static class Parser extends AbstractComponent {
|
||||||
|
|
||||||
public static final ParseField ALERT_NAME_FIELD = new ParseField("alert_name");
|
public static final ParseField WATCH_NAME_FIELD = new ParseField("watch_name");
|
||||||
public static final ParseField FIRE_TIME_FIELD = new ParseField("fire_time");
|
public static final ParseField FIRE_TIME_FIELD = new ParseField("fire_time");
|
||||||
public static final ParseField SCHEDULED_FIRE_TIME_FIELD = new ParseField("scheduled_fire_time");
|
public static final ParseField SCHEDULED_FIRE_TIME_FIELD = new ParseField("scheduled_fire_time");
|
||||||
public static final ParseField MESSAGE_FIELD = new ParseField("message");
|
public static final ParseField MESSAGE_FIELD = new ParseField("message");
|
||||||
public static final ParseField STATE_FIELD = new ParseField("state");
|
public static final ParseField STATE_FIELD = new ParseField("state");
|
||||||
public static final ParseField METADATA_FIELD = new ParseField("meta");
|
public static final ParseField METADATA_FIELD = new ParseField("meta");
|
||||||
public static final ParseField ALERT_EXECUTION_FIELD = new ParseField("alert_execution");
|
public static final ParseField WATCH_EXECUTION_FIELD = new ParseField("watch_execution");
|
||||||
|
|
||||||
private final ConditionRegistry conditionRegistry;
|
private final ConditionRegistry conditionRegistry;
|
||||||
private final ActionRegistry actionRegistry;
|
private final ActionRegistry actionRegistry;
|
||||||
|
@ -225,18 +225,18 @@ public class FiredAlert implements ToXContent {
|
||||||
this.transformRegistry = transformRegistry;
|
this.transformRegistry = transformRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FiredAlert parse(BytesReference source, String historyId, long version) {
|
public WatchRecord parse(BytesReference source, String historyId, long version) {
|
||||||
try (XContentParser parser = XContentHelper.createParser(source)) {
|
try (XContentParser parser = XContentHelper.createParser(source)) {
|
||||||
return parse(parser, historyId, version);
|
return parse(parser, historyId, version);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ElasticsearchException("Error during parsing alert record", e);
|
throw new ElasticsearchException("unable to parse watch record", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public FiredAlert parse(XContentParser parser, String id, long version) throws IOException {
|
public WatchRecord parse(XContentParser parser, String id, long version) throws IOException {
|
||||||
FiredAlert alert = new FiredAlert();
|
WatchRecord record = new WatchRecord();
|
||||||
alert.id = id;
|
record.id = id;
|
||||||
alert.version = version;
|
record.version = version;
|
||||||
|
|
||||||
String currentFieldName = null;
|
String currentFieldName = null;
|
||||||
XContentParser.Token token = parser.nextToken();
|
XContentParser.Token token = parser.nextToken();
|
||||||
|
@ -245,37 +245,37 @@ public class FiredAlert implements ToXContent {
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if (Alert.Parser.INPUT_FIELD.match(currentFieldName)) {
|
if (Watch.Parser.INPUT_FIELD.match(currentFieldName)) {
|
||||||
alert.input = inputRegistry.parse(parser);
|
record.input = inputRegistry.parse(parser);
|
||||||
} else if (Alert.Parser.CONDITION_FIELD.match(currentFieldName)) {
|
} else if (Watch.Parser.CONDITION_FIELD.match(currentFieldName)) {
|
||||||
alert.condition = conditionRegistry.parse(parser);
|
record.condition = conditionRegistry.parse(parser);
|
||||||
} else if (METADATA_FIELD.match(currentFieldName)) {
|
} else if (METADATA_FIELD.match(currentFieldName)) {
|
||||||
alert.metadata = parser.map();
|
record.metadata = parser.map();
|
||||||
} else if (ALERT_EXECUTION_FIELD.match(currentFieldName)) {
|
} else if (WATCH_EXECUTION_FIELD.match(currentFieldName)) {
|
||||||
alert.execution = AlertExecution.Parser.parse(parser, conditionRegistry, actionRegistry, inputRegistry, transformRegistry);
|
record.execution = WatchExecution.Parser.parse(parser, conditionRegistry, actionRegistry, inputRegistry, transformRegistry);
|
||||||
} else {
|
} else {
|
||||||
throw new AlertsException("unable to parse fired alert. unexpected field [" + currentFieldName + "]");
|
throw new WatcherException("unable to parse watch record. unexpected field [" + currentFieldName + "]");
|
||||||
}
|
}
|
||||||
} else if (token.isValue()) {
|
} else if (token.isValue()) {
|
||||||
if (ALERT_NAME_FIELD.match(currentFieldName)) {
|
if (WATCH_NAME_FIELD.match(currentFieldName)) {
|
||||||
alert.name = parser.text();
|
record.name = parser.text();
|
||||||
} else if (FIRE_TIME_FIELD.match(currentFieldName)) {
|
} else if (FIRE_TIME_FIELD.match(currentFieldName)) {
|
||||||
alert.fireTime = DateTime.parse(parser.text());
|
record.fireTime = DateTime.parse(parser.text());
|
||||||
} else if (SCHEDULED_FIRE_TIME_FIELD.match(currentFieldName)) {
|
} else if (SCHEDULED_FIRE_TIME_FIELD.match(currentFieldName)) {
|
||||||
alert.scheduledTime = DateTime.parse(parser.text());
|
record.scheduledTime = DateTime.parse(parser.text());
|
||||||
} else if (MESSAGE_FIELD.match(currentFieldName)) {
|
} else if (MESSAGE_FIELD.match(currentFieldName)) {
|
||||||
alert.message = parser.textOrNull();
|
record.message = parser.textOrNull();
|
||||||
} else if (STATE_FIELD.match(currentFieldName)) {
|
} else if (STATE_FIELD.match(currentFieldName)) {
|
||||||
alert.state = State.resolve(parser.text());
|
record.state = State.resolve(parser.text());
|
||||||
} else {
|
} else {
|
||||||
throw new AlertsException("unable to parse fired alert. unexpected field [" + currentFieldName + "]");
|
throw new WatcherException("unable to parse watch record. unexpected field [" + currentFieldName + "]");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new AlertsException("unable to parse fired alert. unexpected token [" + token + "] for [" + currentFieldName + "]");
|
throw new WatcherException("unable to parse watch record. unexpected token [" + token + "] for [" + currentFieldName + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return alert;
|
return record;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,10 +3,10 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.input;
|
package org.elasticsearch.watcher.input;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.ExecutionContext;
|
import org.elasticsearch.watcher.watch.WatchExecutionContext;
|
||||||
import org.elasticsearch.alerts.Payload;
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
|
@ -34,7 +34,7 @@ public abstract class Input<R extends Input.Result> implements ToXContent {
|
||||||
/**
|
/**
|
||||||
* Executes this input
|
* Executes this input
|
||||||
*/
|
*/
|
||||||
public abstract R execute(ExecutionContext ctx) throws IOException;
|
public abstract R execute(WatchExecutionContext ctx) throws IOException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -3,12 +3,12 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.input;
|
package org.elasticsearch.watcher.input;
|
||||||
|
|
||||||
import org.elasticsearch.action.search.SearchRequest;
|
import org.elasticsearch.action.search.SearchRequest;
|
||||||
import org.elasticsearch.action.search.SearchRequestBuilder;
|
import org.elasticsearch.action.search.SearchRequestBuilder;
|
||||||
import org.elasticsearch.alerts.input.search.SearchInput;
|
import org.elasticsearch.watcher.input.search.SearchInput;
|
||||||
import org.elasticsearch.alerts.input.simple.SimpleInput;
|
import org.elasticsearch.watcher.input.simple.SimpleInput;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
|
@ -3,14 +3,14 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.input;
|
package org.elasticsearch.watcher.input;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.AlertsException;
|
import org.elasticsearch.watcher.WatcherException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class InputException extends AlertsException {
|
public class InputException extends WatcherException {
|
||||||
|
|
||||||
public InputException(String msg) {
|
public InputException(String msg) {
|
||||||
super(msg);
|
super(msg);
|
|
@ -3,10 +3,10 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.input;
|
package org.elasticsearch.watcher.input;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.input.search.SearchInput;
|
import org.elasticsearch.watcher.input.search.SearchInput;
|
||||||
import org.elasticsearch.alerts.input.simple.SimpleInput;
|
import org.elasticsearch.watcher.input.simple.SimpleInput;
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
import org.elasticsearch.common.inject.AbstractModule;
|
||||||
import org.elasticsearch.common.inject.multibindings.MapBinder;
|
import org.elasticsearch.common.inject.multibindings.MapBinder;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.input;
|
package org.elasticsearch.watcher.input;
|
||||||
|
|
||||||
import org.elasticsearch.common.collect.ImmutableMap;
|
import org.elasticsearch.common.collect.ImmutableMap;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
|
@ -3,10 +3,10 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.input;
|
package org.elasticsearch.watcher.input;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.ExecutionContext;
|
import org.elasticsearch.watcher.watch.WatchExecutionContext;
|
||||||
import org.elasticsearch.alerts.Payload;
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
import org.elasticsearch.common.collect.ImmutableMap;
|
import org.elasticsearch.common.collect.ImmutableMap;
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
import org.elasticsearch.common.component.AbstractComponent;
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
|
@ -46,7 +46,7 @@ public class NoneInput extends Input<NoneInput.Result> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result execute(ExecutionContext ctx) throws IOException {
|
public Result execute(WatchExecutionContext ctx) throws IOException {
|
||||||
return Result.INSTANCE;
|
return Result.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,20 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.input.search;
|
package org.elasticsearch.watcher.input.search;
|
||||||
|
|
||||||
import org.elasticsearch.action.search.SearchRequest;
|
import org.elasticsearch.action.search.SearchRequest;
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.action.search.SearchType;
|
import org.elasticsearch.action.search.SearchType;
|
||||||
import org.elasticsearch.alerts.ExecutionContext;
|
import org.elasticsearch.watcher.watch.WatchExecutionContext;
|
||||||
import org.elasticsearch.alerts.Payload;
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
import org.elasticsearch.alerts.input.Input;
|
import org.elasticsearch.watcher.input.Input;
|
||||||
import org.elasticsearch.alerts.input.InputException;
|
import org.elasticsearch.watcher.input.InputException;
|
||||||
import org.elasticsearch.alerts.support.AlertUtils;
|
import org.elasticsearch.watcher.support.WatcherUtils;
|
||||||
import org.elasticsearch.alerts.support.SearchRequestEquivalence;
|
import org.elasticsearch.watcher.support.SearchRequestEquivalence;
|
||||||
import org.elasticsearch.alerts.support.Variables;
|
import org.elasticsearch.watcher.support.Variables;
|
||||||
import org.elasticsearch.alerts.support.init.proxy.ClientProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
import org.elasticsearch.alerts.support.init.proxy.ScriptServiceProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
|
@ -37,10 +37,10 @@ import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.elasticsearch.alerts.support.AlertsDateUtils.formatDate;
|
import static org.elasticsearch.watcher.support.WatcherDateUtils.formatDate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class just defines an input that runs a search
|
* An input that executes search and returns the search response as the initial payload
|
||||||
*/
|
*/
|
||||||
public class SearchInput extends Input<SearchInput.Result> {
|
public class SearchInput extends Input<SearchInput.Result> {
|
||||||
|
|
||||||
|
@ -66,17 +66,17 @@ public class SearchInput extends Input<SearchInput.Result> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result execute(ExecutionContext ctx) throws IOException {
|
public Result execute(WatchExecutionContext ctx) throws IOException {
|
||||||
|
|
||||||
SearchRequest request = createSearchRequestWithTimes(this.searchRequest, ctx.scheduledTime(), ctx.fireTime(), ctx.executionTime(), scriptService);
|
SearchRequest request = createSearchRequestWithTimes(this.searchRequest, ctx.scheduledTime(), ctx.fireTime(), ctx.executionTime(), scriptService);
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("[{}] running query for [{}] [{}]", ctx.id(), ctx.alert().name(), XContentHelper.convertToJson(request.source(), false, true));
|
logger.trace("[{}] running query for [{}] [{}]", ctx.id(), ctx.watch().name(), XContentHelper.convertToJson(request.source(), false, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// actionGet deals properly with InterruptedException
|
// actionGet deals properly with InterruptedException
|
||||||
SearchResponse response = client.search(request);
|
SearchResponse response = client.search(request);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("[{}] found [{}] hits", ctx.id(), ctx.alert().name(), response.getHits().getTotalHits());
|
logger.debug("[{}] found [{}] hits", ctx.id(), ctx.watch().name(), response.getHits().getTotalHits());
|
||||||
for (SearchHit hit : response.getHits()) {
|
for (SearchHit hit : response.getHits()) {
|
||||||
logger.debug("[{}] hit [{}]", ctx.id(), XContentHelper.toString(hit));
|
logger.debug("[{}] hit [{}]", ctx.id(), XContentHelper.toString(hit));
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ public class SearchInput extends Input<SearchInput.Result> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
return AlertUtils.writeSearchRequest(searchRequest, builder, params);
|
return WatcherUtils.writeSearchRequest(searchRequest, builder, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -153,7 +153,7 @@ public class SearchInput extends Input<SearchInput.Result> {
|
||||||
@Override
|
@Override
|
||||||
protected XContentBuilder toXContentBody(XContentBuilder builder, Params params) throws IOException {
|
protected XContentBuilder toXContentBody(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.field(Parser.REQUEST_FIELD.getPreferredName());
|
builder.field(Parser.REQUEST_FIELD.getPreferredName());
|
||||||
return AlertUtils.writeSearchRequest(request, builder, params);
|
return WatcherUtils.writeSearchRequest(request, builder, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ public class SearchInput extends Input<SearchInput.Result> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SearchInput parse(XContentParser parser) throws IOException {
|
public SearchInput parse(XContentParser parser) throws IOException {
|
||||||
SearchRequest request = AlertUtils.readSearchRequest(parser, DEFAULT_SEARCH_TYPE);
|
SearchRequest request = WatcherUtils.readSearchRequest(parser, DEFAULT_SEARCH_TYPE);
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
throw new InputException("could not parse [search] input. search request is missing or null.");
|
throw new InputException("could not parse [search] input. search request is missing or null.");
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ public class SearchInput extends Input<SearchInput.Result> {
|
||||||
if (Input.Result.PAYLOAD_FIELD.match(currentFieldName)) {
|
if (Input.Result.PAYLOAD_FIELD.match(currentFieldName)) {
|
||||||
payload = new Payload.XContent(parser);
|
payload = new Payload.XContent(parser);
|
||||||
} else if (REQUEST_FIELD.match(currentFieldName)) {
|
} else if (REQUEST_FIELD.match(currentFieldName)) {
|
||||||
request = AlertUtils.readSearchRequest(parser, DEFAULT_SEARCH_TYPE);
|
request = WatcherUtils.readSearchRequest(parser, DEFAULT_SEARCH_TYPE);
|
||||||
} else {
|
} else {
|
||||||
throw new InputException("unable to parse [" + TYPE + "] input result. unexpected field [" + currentFieldName + "]");
|
throw new InputException("unable to parse [" + TYPE + "] input result. unexpected field [" + currentFieldName + "]");
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ public class SearchInput extends Input<SearchInput.Result> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
return AlertUtils.writeSearchRequest(request, builder, params);
|
return WatcherUtils.writeSearchRequest(request, builder, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,22 +3,20 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.input.simple;
|
package org.elasticsearch.watcher.input.simple;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.ExecutionContext;
|
import org.elasticsearch.watcher.watch.WatchExecutionContext;
|
||||||
import org.elasticsearch.alerts.Payload;
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
import org.elasticsearch.alerts.input.Input;
|
import org.elasticsearch.watcher.input.Input;
|
||||||
import org.elasticsearch.alerts.input.InputException;
|
import org.elasticsearch.watcher.input.InputException;
|
||||||
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;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
|
||||||
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 java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@ -42,7 +40,7 @@ public class SimpleInput extends Input<SimpleInput.Result> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result execute(ExecutionContext ctx) throws IOException {
|
public Result execute(WatchExecutionContext ctx) throws IOException {
|
||||||
return new Result(TYPE, payload);
|
return new Result(TYPE, payload);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* 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.rest;
|
||||||
|
|
||||||
|
import org.elasticsearch.client.Client;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.rest.BaseRestHandler;
|
||||||
|
import org.elasticsearch.rest.RestChannel;
|
||||||
|
import org.elasticsearch.rest.RestController;
|
||||||
|
import org.elasticsearch.rest.RestRequest;
|
||||||
|
import org.elasticsearch.watcher.client.WatcherClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class WatcherRestHandler extends BaseRestHandler {
|
||||||
|
|
||||||
|
protected static String URI_BASE = "_watcher";
|
||||||
|
|
||||||
|
public WatcherRestHandler(Settings settings, RestController controller, Client client) {
|
||||||
|
super(settings, controller, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final void handleRequest(RestRequest request, RestChannel channel, Client client) throws Exception {
|
||||||
|
handleRequest(request, channel, new WatcherClient(client));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void handleRequest(RestRequest request, RestChannel channel, WatcherClient client) throws Exception;
|
||||||
|
}
|
|
@ -3,9 +3,9 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.rest;
|
package org.elasticsearch.watcher.rest;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.rest.action.*;
|
import org.elasticsearch.watcher.rest.action.*;
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
import org.elasticsearch.common.inject.AbstractModule;
|
||||||
import org.elasticsearch.common.inject.Module;
|
import org.elasticsearch.common.inject.Module;
|
||||||
import org.elasticsearch.common.inject.PreProcessModule;
|
import org.elasticsearch.common.inject.PreProcessModule;
|
||||||
|
@ -14,18 +14,19 @@ import org.elasticsearch.rest.RestModule;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class AlertsRestModule extends AbstractModule implements PreProcessModule {
|
public class WatcherRestModule extends AbstractModule implements PreProcessModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processModule(Module module) {
|
public void processModule(Module module) {
|
||||||
if (module instanceof RestModule) {
|
if (module instanceof RestModule) {
|
||||||
RestModule restModule = (RestModule) module;
|
RestModule restModule = (RestModule) module;
|
||||||
restModule.addRestAction(RestPutAlertAction.class);
|
restModule.addRestAction(RestPutWatchAction.class);
|
||||||
restModule.addRestAction(RestDeleteAlertAction.class);
|
restModule.addRestAction(RestDeleteWatchAction.class);
|
||||||
restModule.addRestAction(RestAlertsStatsAction.class);
|
restModule.addRestAction(RestWatcherStatsAction.class);
|
||||||
restModule.addRestAction(RestGetAlertAction.class);
|
restModule.addRestAction(RestWatcherInfoAction.class);
|
||||||
restModule.addRestAction(RestAlertServiceAction.class);
|
restModule.addRestAction(RestGetWatchAction.class);
|
||||||
restModule.addRestAction(RestAckAlertAction.class);
|
restModule.addRestAction(RestWatchServiceAction.class);
|
||||||
|
restModule.addRestAction(RestAckWatchAction.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* 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.rest.action;
|
||||||
|
|
||||||
|
import org.elasticsearch.watcher.rest.WatcherRestHandler;
|
||||||
|
import org.elasticsearch.watcher.watch.Watch;
|
||||||
|
import org.elasticsearch.watcher.client.WatcherClient;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.ack.AckWatchRequest;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.ack.AckWatchResponse;
|
||||||
|
import org.elasticsearch.client.Client;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.rest.*;
|
||||||
|
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rest action to ack a watch
|
||||||
|
*/
|
||||||
|
public class RestAckWatchAction extends WatcherRestHandler {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected RestAckWatchAction(Settings settings, RestController controller, Client client) {
|
||||||
|
super(settings, controller, client);
|
||||||
|
controller.registerHandler(RestRequest.Method.PUT, URI_BASE + "/watch/{name}/_ack", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleRequest(RestRequest request, RestChannel restChannel, WatcherClient client) throws Exception {
|
||||||
|
AckWatchRequest ackWatchRequest = new AckWatchRequest(request.param("name"));
|
||||||
|
client.ackWatch(ackWatchRequest, new RestBuilderListener<AckWatchResponse>(restChannel) {
|
||||||
|
@Override
|
||||||
|
public RestResponse buildResponse(AckWatchResponse response, XContentBuilder builder) throws Exception {
|
||||||
|
return new BytesRestResponse(RestStatus.OK, builder.startObject()
|
||||||
|
.field(Watch.Parser.STATUS_FIELD.getPreferredName(), response.getStatus().toString())
|
||||||
|
.endObject());
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,19 +3,19 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.rest.action;
|
package org.elasticsearch.watcher.rest.action;
|
||||||
|
|
||||||
import org.elasticsearch.action.delete.DeleteResponse;
|
import org.elasticsearch.action.delete.DeleteResponse;
|
||||||
import org.elasticsearch.alerts.AlertsStore;
|
|
||||||
import org.elasticsearch.alerts.client.AlertsClient;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.delete.DeleteAlertRequest;
|
|
||||||
import org.elasticsearch.alerts.transport.actions.delete.DeleteAlertResponse;
|
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.rest.*;
|
import org.elasticsearch.rest.*;
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
||||||
|
import org.elasticsearch.watcher.client.WatcherClient;
|
||||||
|
import org.elasticsearch.watcher.rest.WatcherRestHandler;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.delete.DeleteWatchRequest;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.delete.DeleteWatchResponse;
|
||||||
|
|
||||||
import static org.elasticsearch.rest.RestRequest.Method.DELETE;
|
import static org.elasticsearch.rest.RestRequest.Method.DELETE;
|
||||||
import static org.elasticsearch.rest.RestStatus.NOT_FOUND;
|
import static org.elasticsearch.rest.RestStatus.NOT_FOUND;
|
||||||
|
@ -23,36 +23,27 @@ import static org.elasticsearch.rest.RestStatus.OK;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class RestDeleteAlertAction extends BaseRestHandler {
|
public class RestDeleteWatchAction extends WatcherRestHandler {
|
||||||
|
|
||||||
private final AlertsClient alertsClient;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RestDeleteAlertAction(Settings settings, RestController controller, Client client, AlertsClient alertsClient) {
|
public RestDeleteWatchAction(Settings settings, RestController controller, Client client) {
|
||||||
super(settings, controller, client);
|
super(settings, controller, client);
|
||||||
this.alertsClient = alertsClient;
|
controller.registerHandler(DELETE, URI_BASE + "/watch/{name}", this);
|
||||||
controller.registerHandler(DELETE, AlertsStore.ALERT_INDEX + "/alert/{name}", this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleRequest(RestRequest request, RestChannel channel, Client client) throws Exception {
|
protected void handleRequest(RestRequest request, RestChannel channel, WatcherClient client) throws Exception {
|
||||||
DeleteAlertRequest indexAlertRequest = new DeleteAlertRequest();
|
DeleteWatchRequest indexWatchRequest = new DeleteWatchRequest(request.param("name"));
|
||||||
indexAlertRequest.setAlertName(request.param("name"));
|
client.deleteWatch(indexWatchRequest, new RestBuilderListener<DeleteWatchResponse>(channel) {
|
||||||
alertsClient.deleteAlert(indexAlertRequest, new RestBuilderListener<DeleteAlertResponse>(channel) {
|
|
||||||
@Override
|
@Override
|
||||||
public RestResponse buildResponse(DeleteAlertResponse result, XContentBuilder builder) throws Exception {
|
public RestResponse buildResponse(DeleteWatchResponse result, XContentBuilder builder) throws Exception {
|
||||||
DeleteResponse deleteResponse = result.deleteResponse();
|
DeleteResponse deleteResponse = result.deleteResponse();
|
||||||
builder.startObject()
|
builder.startObject()
|
||||||
.field("found", deleteResponse.isFound())
|
.field("found", deleteResponse.isFound())
|
||||||
.field("_index", deleteResponse.getIndex())
|
|
||||||
.field("_type", deleteResponse.getType())
|
|
||||||
.field("_id", deleteResponse.getId())
|
.field("_id", deleteResponse.getId())
|
||||||
.field("_version", deleteResponse.getVersion())
|
.field("_version", deleteResponse.getVersion())
|
||||||
.endObject();
|
.endObject();
|
||||||
RestStatus status = OK;
|
RestStatus status = deleteResponse.isFound() ? OK : NOT_FOUND;
|
||||||
if (!deleteResponse.isFound()) {
|
|
||||||
status = NOT_FOUND;
|
|
||||||
}
|
|
||||||
return new BytesRestResponse(status, builder);
|
return new BytesRestResponse(status, builder);
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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.rest.action;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.get.GetResponse;
|
||||||
|
import org.elasticsearch.client.Client;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.rest.*;
|
||||||
|
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
||||||
|
import org.elasticsearch.watcher.client.WatcherClient;
|
||||||
|
import org.elasticsearch.watcher.rest.WatcherRestHandler;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.get.GetWatchRequest;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.get.GetWatchResponse;
|
||||||
|
|
||||||
|
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
||||||
|
import static org.elasticsearch.rest.RestStatus.NOT_FOUND;
|
||||||
|
import static org.elasticsearch.rest.RestStatus.OK;
|
||||||
|
|
||||||
|
public class RestGetWatchAction extends WatcherRestHandler {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public RestGetWatchAction(Settings settings, RestController controller, Client client) {
|
||||||
|
super(settings, controller, client);
|
||||||
|
controller.registerHandler(GET, URI_BASE + "/watch/{name}", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleRequest(RestRequest request, RestChannel channel, WatcherClient client) throws Exception {
|
||||||
|
final GetWatchRequest getWatchRequest = new GetWatchRequest(request.param("name"));
|
||||||
|
client.getWatch(getWatchRequest, new RestBuilderListener<GetWatchResponse>(channel) {
|
||||||
|
@Override
|
||||||
|
public RestResponse buildResponse(GetWatchResponse response, XContentBuilder builder) throws Exception {
|
||||||
|
GetResponse getResponse = response.getResponse();
|
||||||
|
builder.startObject()
|
||||||
|
.field("found", getResponse.isExists())
|
||||||
|
.field("_id", getResponse.getId())
|
||||||
|
.field("_version", getResponse.getVersion())
|
||||||
|
.field("watch", getResponse.getSource())
|
||||||
|
.endObject();
|
||||||
|
|
||||||
|
RestStatus status = getResponse.isExists() ? OK : NOT_FOUND;
|
||||||
|
return new BytesRestResponse(status, builder);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* 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.rest.action;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.index.IndexResponse;
|
||||||
|
import org.elasticsearch.client.Client;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.rest.*;
|
||||||
|
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
||||||
|
import org.elasticsearch.watcher.client.WatcherClient;
|
||||||
|
import org.elasticsearch.watcher.rest.WatcherRestHandler;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.put.PutWatchRequest;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.put.PutWatchResponse;
|
||||||
|
|
||||||
|
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
||||||
|
import static org.elasticsearch.rest.RestRequest.Method.PUT;
|
||||||
|
import static org.elasticsearch.rest.RestStatus.CREATED;
|
||||||
|
import static org.elasticsearch.rest.RestStatus.OK;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public class RestPutWatchAction extends WatcherRestHandler {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public RestPutWatchAction(Settings settings, RestController controller, Client client) {
|
||||||
|
super(settings, controller, client);
|
||||||
|
controller.registerHandler(POST, URI_BASE + "/watch/{name}", this);
|
||||||
|
controller.registerHandler(PUT, URI_BASE + "/watch/{name}", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleRequest(RestRequest request, RestChannel channel, WatcherClient client) throws Exception {
|
||||||
|
PutWatchRequest putWatchRequest = new PutWatchRequest(request.param("name"), request.content(), request.contentUnsafe());
|
||||||
|
client.putWatch(putWatchRequest, new RestBuilderListener<PutWatchResponse>(channel) {
|
||||||
|
@Override
|
||||||
|
public RestResponse buildResponse(PutWatchResponse response, XContentBuilder builder) throws Exception {
|
||||||
|
IndexResponse indexResponse = response.indexResponse();
|
||||||
|
builder.startObject()
|
||||||
|
.field("_id", indexResponse.getId())
|
||||||
|
.field("_version", indexResponse.getVersion())
|
||||||
|
.field("created", indexResponse.isCreated())
|
||||||
|
.endObject();
|
||||||
|
RestStatus status = indexResponse.isCreated() ? CREATED : OK;
|
||||||
|
return new BytesRestResponse(status, builder);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* 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.rest.action;
|
||||||
|
|
||||||
|
import org.elasticsearch.watcher.watch.WatchStore;
|
||||||
|
import org.elasticsearch.watcher.client.WatcherClient;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.service.WatcherServiceRequest;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.service.WatcherServiceResponse;
|
||||||
|
import org.elasticsearch.client.Client;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.rest.BaseRestHandler;
|
||||||
|
import org.elasticsearch.rest.RestChannel;
|
||||||
|
import org.elasticsearch.rest.RestController;
|
||||||
|
import org.elasticsearch.rest.RestRequest;
|
||||||
|
import org.elasticsearch.rest.action.support.AcknowledgedRestListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public class RestWatchServiceAction extends BaseRestHandler {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected RestWatchServiceAction(Settings settings, RestController controller, Client client) {
|
||||||
|
super(settings, controller, client);
|
||||||
|
controller.registerHandler(RestRequest.Method.PUT, WatchStore.INDEX + "/_restart", this);
|
||||||
|
controller.registerHandler(RestRequest.Method.PUT, WatchStore.INDEX + "/_start", new StartRestHandler(settings, controller, client));
|
||||||
|
controller.registerHandler(RestRequest.Method.PUT, WatchStore.INDEX + "/_stop", new StopRestHandler(settings, controller, client));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleRequest(RestRequest request, RestChannel channel, Client client) throws Exception {
|
||||||
|
new WatcherClient(client).watcherService(new WatcherServiceRequest().restart(), new AcknowledgedRestListener<WatcherServiceResponse>(channel));
|
||||||
|
}
|
||||||
|
|
||||||
|
static class StartRestHandler extends BaseRestHandler {
|
||||||
|
|
||||||
|
public StartRestHandler(Settings settings, RestController controller, Client client) {
|
||||||
|
super(settings, controller, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleRequest(RestRequest request, RestChannel channel, Client client) throws Exception {
|
||||||
|
new WatcherClient(client).watcherService(new WatcherServiceRequest().start(), new AcknowledgedRestListener<WatcherServiceResponse>(channel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class StopRestHandler extends BaseRestHandler {
|
||||||
|
|
||||||
|
public StopRestHandler(Settings settings, RestController controller, Client client) {
|
||||||
|
super(settings, controller, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleRequest(RestRequest request, RestChannel channel, Client client) throws Exception {
|
||||||
|
new WatcherClient(client).watcherService(new WatcherServiceRequest().stop(), new AcknowledgedRestListener<WatcherServiceResponse>(channel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* 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.rest.action;
|
||||||
|
|
||||||
|
import org.elasticsearch.client.Client;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.rest.*;
|
||||||
|
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
||||||
|
import org.elasticsearch.watcher.client.WatcherClient;
|
||||||
|
import org.elasticsearch.watcher.rest.WatcherRestHandler;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.stats.WatcherStatsResponse;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.stats.WatcherStatsRequest;
|
||||||
|
|
||||||
|
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
||||||
|
import static org.elasticsearch.rest.RestStatus.OK;
|
||||||
|
|
||||||
|
public class RestWatcherInfoAction extends WatcherRestHandler {
|
||||||
|
|
||||||
|
private final WatcherClient watcherClient;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected RestWatcherInfoAction(Settings settings, RestController controller, Client client, WatcherClient watcherClient) {
|
||||||
|
super(settings, controller, client);
|
||||||
|
this.watcherClient = watcherClient;
|
||||||
|
controller.registerHandler(GET, URI_BASE, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleRequest(RestRequest request, RestChannel restChannel, WatcherClient client) throws Exception {
|
||||||
|
watcherClient.watcherStats(new WatcherStatsRequest(), new RestBuilderListener<WatcherStatsResponse>(restChannel) {
|
||||||
|
@Override
|
||||||
|
public RestResponse buildResponse(WatcherStatsResponse watcherStatsResponse, XContentBuilder builder) throws Exception {
|
||||||
|
builder.startObject("version")
|
||||||
|
.field("number", watcherStatsResponse.getVersion().number())
|
||||||
|
.field("build_hash", watcherStatsResponse.getBuild().hash())
|
||||||
|
.field("build_timestamp", watcherStatsResponse.getBuild().timestamp())
|
||||||
|
.field("build_snapshot", watcherStatsResponse.getVersion().snapshot)
|
||||||
|
.endObject();
|
||||||
|
|
||||||
|
return new BytesRestResponse(OK, builder);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* 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.rest.action;
|
||||||
|
|
||||||
|
import org.elasticsearch.client.Client;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.rest.*;
|
||||||
|
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
||||||
|
import org.elasticsearch.watcher.client.WatcherClient;
|
||||||
|
import org.elasticsearch.watcher.rest.WatcherRestHandler;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.stats.WatcherStatsResponse;
|
||||||
|
import org.elasticsearch.watcher.transport.actions.stats.WatcherStatsRequest;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
||||||
|
import static org.elasticsearch.rest.RestStatus.OK;
|
||||||
|
|
||||||
|
public class RestWatcherStatsAction extends WatcherRestHandler {
|
||||||
|
|
||||||
|
private final WatcherClient watcherClient;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected RestWatcherStatsAction(Settings settings, RestController controller, Client client, WatcherClient watcherClient) {
|
||||||
|
super(settings, controller, client);
|
||||||
|
this.watcherClient = watcherClient;
|
||||||
|
controller.registerHandler(GET, URI_BASE + "/stats", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleRequest(RestRequest request, RestChannel restChannel, WatcherClient client) throws Exception {
|
||||||
|
watcherClient.watcherStats(new WatcherStatsRequest(), new RestBuilderListener<WatcherStatsResponse>(restChannel) {
|
||||||
|
@Override
|
||||||
|
public RestResponse buildResponse(WatcherStatsResponse watcherStatsResponse, XContentBuilder builder) throws Exception {
|
||||||
|
builder.field("watch_service_state", watcherStatsResponse.getWatchServiceState().toString().toLowerCase(Locale.ROOT))
|
||||||
|
.field("watch_count", watcherStatsResponse.getWatchesCount());
|
||||||
|
|
||||||
|
builder.startObject("execution_queue")
|
||||||
|
.field("size", watcherStatsResponse.getExecutionQueueSize())
|
||||||
|
.field("max_size", watcherStatsResponse.getWatchExecutionQueueMaxSize())
|
||||||
|
.endObject();
|
||||||
|
|
||||||
|
return new BytesRestResponse(OK, builder);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,14 +3,14 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.scheduler;
|
package org.elasticsearch.watcher.scheduler;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.AlertsPlugin;
|
import org.elasticsearch.watcher.WatcherPlugin;
|
||||||
import org.elasticsearch.alerts.AlertsSettingsException;
|
import org.elasticsearch.watcher.WatcherSettingsException;
|
||||||
import org.elasticsearch.alerts.scheduler.schedule.CronnableSchedule;
|
import org.elasticsearch.watcher.scheduler.schedule.CronnableSchedule;
|
||||||
import org.elasticsearch.alerts.scheduler.schedule.IntervalSchedule;
|
import org.elasticsearch.watcher.scheduler.schedule.IntervalSchedule;
|
||||||
import org.elasticsearch.alerts.scheduler.schedule.Schedule;
|
import org.elasticsearch.watcher.scheduler.schedule.Schedule;
|
||||||
import org.elasticsearch.alerts.support.clock.Clock;
|
import org.elasticsearch.watcher.support.clock.Clock;
|
||||||
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.joda.time.DateTime;
|
import org.elasticsearch.common.joda.time.DateTime;
|
||||||
|
@ -25,7 +25,7 @@ import org.quartz.simpl.SimpleJobFactory;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import static org.elasticsearch.alerts.scheduler.FireAlertQuartzJob.jobDetail;
|
import static org.elasticsearch.watcher.scheduler.WatcherQuartzJob.jobDetail;
|
||||||
|
|
||||||
public class InternalScheduler extends AbstractComponent implements Scheduler {
|
public class InternalScheduler extends AbstractComponent implements Scheduler {
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ public class InternalScheduler extends AbstractComponent implements Scheduler {
|
||||||
try {
|
try {
|
||||||
this.defaultTimeZone = DateTimeZone.forID(timeZoneStr);
|
this.defaultTimeZone = DateTimeZone.forID(timeZoneStr);
|
||||||
} catch (IllegalArgumentException iae) {
|
} catch (IllegalArgumentException iae) {
|
||||||
throw new AlertsSettingsException("unrecognized time zone setting [" + timeZoneStr + "]", iae);
|
throw new WatcherSettingsException("unrecognized time zone setting [" + timeZoneStr + "]", iae);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ public class InternalScheduler extends AbstractComponent implements Scheduler {
|
||||||
logger.info("Starting scheduler");
|
logger.info("Starting scheduler");
|
||||||
// Can't start a scheduler that has been shutdown, so we need to re-create each time start() is invoked
|
// Can't start a scheduler that has been shutdown, so we need to re-create each time start() is invoked
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.setProperty("org.quartz.threadPool.class", AlertQuartzThreadPool.class.getName());
|
properties.setProperty("org.quartz.threadPool.class", WatcherQuartzThreadPool.class.getName());
|
||||||
properties.setProperty(StdSchedulerFactory.PROP_SCHED_SKIP_UPDATE_CHECK, "true");
|
properties.setProperty(StdSchedulerFactory.PROP_SCHED_SKIP_UPDATE_CHECK, "true");
|
||||||
properties.setProperty(StdSchedulerFactory.PROP_SCHED_INTERRUPT_JOBS_ON_SHUTDOWN, "true");
|
properties.setProperty(StdSchedulerFactory.PROP_SCHED_INTERRUPT_JOBS_ON_SHUTDOWN, "true");
|
||||||
properties.setProperty(StdSchedulerFactory.PROP_SCHED_INTERRUPT_JOBS_ON_SHUTDOWN_WITH_WAIT, "true");
|
properties.setProperty(StdSchedulerFactory.PROP_SCHED_INTERRUPT_JOBS_ON_SHUTDOWN_WITH_WAIT, "true");
|
||||||
|
@ -67,8 +67,8 @@ public class InternalScheduler extends AbstractComponent implements Scheduler {
|
||||||
scheduler = schFactory.getScheduler();
|
scheduler = schFactory.getScheduler();
|
||||||
scheduler.setJobFactory(new SimpleJobFactory());
|
scheduler.setJobFactory(new SimpleJobFactory());
|
||||||
Map<JobDetail, Set<? extends Trigger>> quartzJobs = new HashMap<>();
|
Map<JobDetail, Set<? extends Trigger>> quartzJobs = new HashMap<>();
|
||||||
for (Job alert : jobs) {
|
for (Job job : jobs) {
|
||||||
quartzJobs.put(jobDetail(alert.name(), this), createTrigger(alert.schedule(), defaultTimeZone, clock));
|
quartzJobs.put(jobDetail(job.name(), this), createTrigger(job.schedule(), defaultTimeZone, clock));
|
||||||
}
|
}
|
||||||
scheduler.scheduleJobs(quartzJobs, false);
|
scheduler.scheduleJobs(quartzJobs, false);
|
||||||
scheduler.start();
|
scheduler.start();
|
||||||
|
@ -96,16 +96,16 @@ public class InternalScheduler extends AbstractComponent implements Scheduler {
|
||||||
listeners.add(listener);
|
listeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
void notifyListeners(String alertName, JobExecutionContext ctx) {
|
void notifyListeners(String name, JobExecutionContext ctx) {
|
||||||
DateTime scheduledTime = new DateTime(ctx.getScheduledFireTime());
|
DateTime scheduledTime = new DateTime(ctx.getScheduledFireTime());
|
||||||
DateTime fireTime = new DateTime(ctx.getFireTime());
|
DateTime fireTime = new DateTime(ctx.getFireTime());
|
||||||
for (Listener listener : listeners) {
|
for (Listener listener : listeners) {
|
||||||
listener.fire(alertName, scheduledTime, fireTime);
|
listener.fire(name, scheduledTime, fireTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedules the given alert
|
* Schedules the given job
|
||||||
*/
|
*/
|
||||||
public void add(Job job) {
|
public void add(Job job) {
|
||||||
try {
|
try {
|
||||||
|
@ -147,13 +147,13 @@ public class InternalScheduler extends AbstractComponent implements Scheduler {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This Quartz thread pool will always accept. On this thread we will only index an alert action and add it to the work queue
|
// This Quartz thread pool will always accept. On this thread we will only index a watch record and add it to the work queue
|
||||||
public static final class AlertQuartzThreadPool implements org.quartz.spi.ThreadPool {
|
public static final class WatcherQuartzThreadPool implements org.quartz.spi.ThreadPool {
|
||||||
|
|
||||||
private final EsThreadPoolExecutor executor;
|
private final EsThreadPoolExecutor executor;
|
||||||
|
|
||||||
public AlertQuartzThreadPool() {
|
public WatcherQuartzThreadPool() {
|
||||||
this.executor = (EsThreadPoolExecutor) threadPool.executor(AlertsPlugin.SCHEDULER_THREAD_POOL_NAME);
|
this.executor = (EsThreadPoolExecutor) threadPool.executor(WatcherPlugin.SCHEDULER_THREAD_POOL_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -3,9 +3,9 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.scheduler;
|
package org.elasticsearch.watcher.scheduler;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.scheduler.schedule.Schedule;
|
import org.elasticsearch.watcher.scheduler.schedule.Schedule;
|
||||||
import org.elasticsearch.common.joda.time.DateTime;
|
import org.elasticsearch.common.joda.time.DateTime;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
|
@ -3,14 +3,14 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.scheduler;
|
package org.elasticsearch.watcher.scheduler;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.AlertsException;
|
import org.elasticsearch.watcher.WatcherException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SchedulerException extends AlertsException {
|
public class SchedulerException extends WatcherException {
|
||||||
|
|
||||||
public SchedulerException(String msg) {
|
public SchedulerException(String msg) {
|
||||||
super(msg);
|
super(msg);
|
|
@ -3,9 +3,9 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.scheduler;
|
package org.elasticsearch.watcher.scheduler;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.scheduler.schedule.*;
|
import org.elasticsearch.watcher.scheduler.schedule.*;
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
import org.elasticsearch.common.inject.AbstractModule;
|
||||||
import org.elasticsearch.common.inject.multibindings.MapBinder;
|
import org.elasticsearch.common.inject.multibindings.MapBinder;
|
||||||
|
|
|
@ -3,30 +3,30 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.scheduler;
|
package org.elasticsearch.watcher.scheduler;
|
||||||
|
|
||||||
import org.quartz.*;
|
import org.quartz.*;
|
||||||
|
|
||||||
public class FireAlertQuartzJob implements Job {
|
public class WatcherQuartzJob implements Job {
|
||||||
|
|
||||||
static final String SCHEDULER_KEY = "scheduler";
|
static final String SCHEDULER_KEY = "scheduler";
|
||||||
|
|
||||||
public FireAlertQuartzJob() {
|
public WatcherQuartzJob() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||||
String alertName = jobExecutionContext.getJobDetail().getKey().getName();
|
String watchName = jobExecutionContext.getJobDetail().getKey().getName();
|
||||||
InternalScheduler scheduler = (InternalScheduler) jobExecutionContext.getJobDetail().getJobDataMap().get(SCHEDULER_KEY);
|
InternalScheduler scheduler = (InternalScheduler) jobExecutionContext.getJobDetail().getJobDataMap().get(SCHEDULER_KEY);
|
||||||
scheduler.notifyListeners(alertName, jobExecutionContext);
|
scheduler.notifyListeners(watchName, jobExecutionContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JobKey jobKey(String alertName) {
|
static JobKey jobKey(String watchName) {
|
||||||
return new JobKey(alertName);
|
return new JobKey(watchName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JobDetail jobDetail(String alertName, InternalScheduler scheduler) {
|
static JobDetail jobDetail(String watchName, InternalScheduler scheduler) {
|
||||||
JobDetail job = JobBuilder.newJob(FireAlertQuartzJob.class).withIdentity(alertName).build();
|
JobDetail job = JobBuilder.newJob(WatcherQuartzJob.class).withIdentity(watchName).build();
|
||||||
job.getJobDataMap().put("scheduler", scheduler);
|
job.getJobDataMap().put("scheduler", scheduler);
|
||||||
return job;
|
return job;
|
||||||
}
|
}
|
|
@ -3,9 +3,9 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.scheduler.schedule;
|
package org.elasticsearch.watcher.scheduler.schedule;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.AlertsSettingsException;
|
import org.elasticsearch.watcher.WatcherSettingsException;
|
||||||
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.quartz.CronExpression;
|
import org.quartz.CronExpression;
|
||||||
|
@ -69,24 +69,24 @@ public class CronSchedule extends CronnableSchedule {
|
||||||
crons.add(parser.text());
|
crons.add(parser.text());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new AlertsSettingsException("could not parse [cron] schedule. expected a string value in the cron array but found [" + token + "]");
|
throw new WatcherSettingsException("could not parse [cron] schedule. expected a string value in the cron array but found [" + token + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (crons.isEmpty()) {
|
if (crons.isEmpty()) {
|
||||||
throw new AlertsSettingsException("could not parse [cron] schedule. no cron expression found in cron array");
|
throw new WatcherSettingsException("could not parse [cron] schedule. no cron expression found in cron array");
|
||||||
}
|
}
|
||||||
return new CronSchedule(crons.toArray(new String[crons.size()]));
|
return new CronSchedule(crons.toArray(new String[crons.size()]));
|
||||||
} else {
|
} else {
|
||||||
throw new AlertsSettingsException("could not parse [cron] schedule. expected either a cron string value or an array of cron string values, but found [" + token + "]");
|
throw new WatcherSettingsException("could not parse [cron] schedule. expected either a cron string value or an array of cron string values, but found [" + token + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (ValidationException ve) {
|
} catch (ValidationException ve) {
|
||||||
throw new AlertsSettingsException("could not parse [cron] schedule. invalid cron expression [" + ve.expression + "]", ve);
|
throw new WatcherSettingsException("could not parse [cron] schedule. invalid cron expression [" + ve.expression + "]", ve);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ValidationException extends AlertsSettingsException {
|
public static class ValidationException extends WatcherSettingsException {
|
||||||
|
|
||||||
private String expression;
|
private String expression;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.scheduler.schedule;
|
package org.elasticsearch.watcher.scheduler.schedule;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
|
@ -3,10 +3,10 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.scheduler.schedule;
|
package org.elasticsearch.watcher.scheduler.schedule;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.AlertsSettingsException;
|
import org.elasticsearch.watcher.WatcherSettingsException;
|
||||||
import org.elasticsearch.alerts.scheduler.schedule.support.DayTimes;
|
import org.elasticsearch.watcher.scheduler.schedule.support.DayTimes;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
@ -92,19 +92,19 @@ public class DailySchedule extends CronnableSchedule {
|
||||||
try {
|
try {
|
||||||
times.add(DayTimes.parse(parser, token));
|
times.add(DayTimes.parse(parser, token));
|
||||||
} catch (DayTimes.ParseException pe) {
|
} catch (DayTimes.ParseException pe) {
|
||||||
throw new AlertsSettingsException("could not parse [daily] schedule. invalid time value for field [at] - [" + token + "]", pe);
|
throw new WatcherSettingsException("could not parse [daily] schedule. invalid time value for field [at] - [" + token + "]", pe);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||||
try {
|
try {
|
||||||
times.add(DayTimes.parse(parser, token));
|
times.add(DayTimes.parse(parser, token));
|
||||||
} catch (DayTimes.ParseException pe) {
|
} catch (DayTimes.ParseException pe) {
|
||||||
throw new AlertsSettingsException("could not parse [daily] schedule. invalid time value for field [at] - [" + token + "]", pe);
|
throw new WatcherSettingsException("could not parse [daily] schedule. invalid time value for field [at] - [" + token + "]", pe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new AlertsSettingsException("could not parse [daily] schedule. unexpected field [" + currentFieldName + "]");
|
throw new WatcherSettingsException("could not parse [daily] schedule. unexpected field [" + currentFieldName + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.alerts.scheduler.schedule;
|
package org.elasticsearch.watcher.scheduler.schedule;
|
||||||
|
|
||||||
import org.elasticsearch.alerts.AlertsSettingsException;
|
import org.elasticsearch.watcher.WatcherSettingsException;
|
||||||
import org.elasticsearch.alerts.scheduler.schedule.support.DayTimes;
|
import org.elasticsearch.watcher.scheduler.schedule.support.DayTimes;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.primitives.Ints;
|
import org.elasticsearch.common.primitives.Ints;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
@ -70,7 +70,7 @@ public class HourlySchedule extends CronnableSchedule {
|
||||||
sb.append(",");
|
sb.append(",");
|
||||||
}
|
}
|
||||||
if (!validMinute(minutes[i])) {
|
if (!validMinute(minutes[i])) {
|
||||||
throw new AlertsSettingsException("invalid hourly minute [" + minutes[i] + "]. minute must be between 0 and 59 incl.");
|
throw new WatcherSettingsException("invalid hourly minute [" + minutes[i] + "]. minute must be between 0 and 59 incl.");
|
||||||
}
|
}
|
||||||
sb.append(minutes[i]);
|
sb.append(minutes[i]);
|
||||||
}
|
}
|
||||||
|
@ -104,21 +104,21 @@ public class HourlySchedule extends CronnableSchedule {
|
||||||
try {
|
try {
|
||||||
minutes.add(DayTimes.parseMinuteValue(parser, token));
|
minutes.add(DayTimes.parseMinuteValue(parser, token));
|
||||||
} catch (DayTimes.ParseException pe) {
|
} catch (DayTimes.ParseException pe) {
|
||||||
throw new AlertsSettingsException("could not parse [hourly] schedule. invalid value for [minute]", pe);
|
throw new WatcherSettingsException("could not parse [hourly] schedule. invalid value for [minute]", pe);
|
||||||
}
|
}
|
||||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||||
try {
|
try {
|
||||||
minutes.add(DayTimes.parseMinuteValue(parser, token));
|
minutes.add(DayTimes.parseMinuteValue(parser, token));
|
||||||
} catch (DayTimes.ParseException pe) {
|
} catch (DayTimes.ParseException pe) {
|
||||||
throw new AlertsSettingsException("could not parse [hourly] schedule. invalid value for [minute]", pe);
|
throw new WatcherSettingsException("could not parse [hourly] schedule. invalid value for [minute]", pe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new AlertsSettingsException("could not parse [hourly] schedule. invalid minute value. expected either string/value or an array of string/number values, but found [" + token + "]");
|
throw new WatcherSettingsException("could not parse [hourly] schedule. invalid minute value. expected either string/value or an array of string/number values, but found [" + token + "]");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new AlertsSettingsException("could not parse [hourly] schedule. unexpected field [" + currentFieldName + "]");
|
throw new WatcherSettingsException("could not parse [hourly] schedule. unexpected field [" + currentFieldName + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue