Cleanup exceptions

Remove all watcher specific/custom exceptions. We're now reusing the standard exceptions used in core.

Original commit: elastic/x-pack-elasticsearch@26090ff6ef
This commit is contained in:
uboness 2015-07-02 16:06:21 +02:00
parent f620907939
commit 287a612179
177 changed files with 984 additions and 1929 deletions

View File

@ -1,23 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.logging.support.LoggerMessageFormat;
/**
* A base class for all watcher exceptions
*/
public class WatcherException extends ElasticsearchException {
public WatcherException(String msg, Object... args) {
super(LoggerMessageFormat.format(msg, args));
}
public WatcherException(String msg, Throwable cause, Object... args) {
super(LoggerMessageFormat.format(msg, args), cause);
}
}

View File

@ -6,13 +6,12 @@
package org.elasticsearch.watcher;
import org.elasticsearch.ElasticsearchTimeoutException;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.joda.time.DateTimeZone;
import org.joda.time.PeriodType;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.engine.VersionConflictEngineException;
@ -23,10 +22,14 @@ import org.elasticsearch.watcher.watch.Watch;
import org.elasticsearch.watcher.watch.WatchLockService;
import org.elasticsearch.watcher.watch.WatchStatus;
import org.elasticsearch.watcher.watch.WatchStore;
import org.joda.time.DateTimeZone;
import org.joda.time.PeriodType;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;
import static org.elasticsearch.watcher.support.Exceptions.*;
public class WatcherService extends AbstractComponent {
@ -50,7 +53,7 @@ public class WatcherService extends AbstractComponent {
this.executionService = executionService;
}
public void start(ClusterState clusterState) {
public void start(ClusterState clusterState) throws Exception {
if (state.compareAndSet(WatcherState.STOPPED, WatcherState.STARTING)) {
try {
logger.info("starting watch service...");
@ -82,8 +85,8 @@ public class WatcherService extends AbstractComponent {
executionService.stop();
try {
watchLockService.stop();
} catch (WatchLockService.TimeoutException we) {
logger.warn("error stopping WatchLockService", we);
} catch (ElasticsearchTimeoutException te) {
logger.warn("error stopping WatchLockService", te);
}
watchStore.stop();
state.set(WatcherState.STOPPED);
@ -99,7 +102,7 @@ public class WatcherService extends AbstractComponent {
if (!force) {
lock = watchLockService.tryAcquire(id, timeout);
if (lock == null) {
throw new TimeoutException("could not delete watch [{}] within [{}]... wait and try again. If this error continues to occur there is a high chance that the watch execution is stuck (either due to unresponsive external system such as an email service, or due to a bad script", id, timeout.format(PeriodType.seconds()));
throw new ElasticsearchTimeoutException("could not delete watch [{}] within [{}]... wait and try again. If this error continues to occur there is a high chance that the watch execution is stuck (either due to unresponsive external system such as an email service, or due to a bad script", id, timeout.format(PeriodType.seconds()));
}
}
try {
@ -115,11 +118,11 @@ public class WatcherService extends AbstractComponent {
}
}
public IndexResponse putWatch(String id, BytesReference watchSource, TimeValue timeout) {
public IndexResponse putWatch(String id, BytesReference watchSource, TimeValue timeout) throws IOException {
ensureStarted();
WatchLockService.Lock lock = watchLockService.tryAcquire(id, timeout);
if (lock == null) {
throw new TimeoutException("could not put watch [{}] within [{}]... wait and try again. If this error continues to occur there is a high chance that the watch execution is stuck (either due to unresponsive external system such as an email service, or due to a bad script", id, timeout.format(PeriodType.seconds()));
throw new ElasticsearchTimeoutException("could not put watch [{}] within [{}]... wait and try again. If this error continues to occur there is a high chance that the watch execution is stuck (either due to unresponsive external system such as an email service, or due to a bad script", id, timeout.format(PeriodType.seconds()));
}
try {
Watch watch = watchParser.parseWithSecrets(id, false, watchSource);
@ -128,9 +131,6 @@ public class WatcherService extends AbstractComponent {
triggerService.add(result.current());
}
return result.indexResponse();
} catch (Exception e) {
logger.warn("failed to put watch [{}]", e, id);
throw new WatcherException("failed to put watch [{}]", e, id);
} finally {
lock.release();
}
@ -150,11 +150,11 @@ public class WatcherService extends AbstractComponent {
/**
* Acks the watch if needed
*/
public WatchStatus ackWatch(String id, String[] actionIds, TimeValue timeout) {
public WatchStatus ackWatch(String id, String[] actionIds, TimeValue timeout) throws IOException {
ensureStarted();
WatchLockService.Lock lock = watchLockService.tryAcquire(id, timeout);
if (lock == null) {
throw new TimeoutException("could not ack watch [{}] within [{}]... wait and try again. If this error continues to occur there is a high chance that the watch execution is stuck (either due to unresponsive external system such as an email service, or due to a bad script", id, timeout.format(PeriodType.seconds()));
throw new ElasticsearchTimeoutException("could not ack watch [{}] within [{}]... wait and try again. If this error continues to occur there is a high chance that the watch execution is stuck (either due to unresponsive external system such as an email service, or due to a bad script", id, timeout.format(PeriodType.seconds()));
}
if (actionIds == null || actionIds.length == 0) {
actionIds = new String[] { Watch.ALL_ACTIONS_ID };
@ -162,16 +162,16 @@ public class WatcherService extends AbstractComponent {
try {
Watch watch = watchStore.get(id);
if (watch == null) {
throw new WatcherException("watch [{}] does not exist", id);
throw illegalArgument("watch [{}] does not exist", id);
}
// we need to create a safe copy of the status
if (watch.ack(clock.now(DateTimeZone.UTC), actionIds)) {
try {
watchStore.updateStatus(watch);
} catch (IOException ioe) {
throw new WatcherException("failed to update the watch [{}] on ack", ioe, watch.id());
throw ioException("failed to update the watch [{}] on ack", ioe, watch.id());
} catch (VersionConflictEngineException vcee) {
throw new WatcherException("failed to update the watch [{}] on ack, perhaps it was force deleted", vcee, watch.id());
throw illegalState("failed to update the watch [{}] on ack, perhaps it was force deleted", vcee, watch.id());
}
}
return new WatchStatus(watch.status());
@ -190,10 +190,4 @@ public class WatcherService extends AbstractComponent {
}
}
public static class TimeoutException extends WatcherException {
public TimeoutException(String msg, Object... args) {
super(msg, args);
}
}
}

View File

@ -48,10 +48,9 @@ public enum WatcherState {
return STARTING;
case 2:
return STARTED;
case 3:
default: //3
assert id == 3 : "unknown watcher state id [" + id + "]";
return STOPPING;
default:
throw new WatcherException("unknown watch service state id [" + id + "]");
}
}
}

View File

@ -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.watcher.actions;
import org.elasticsearch.common.logging.support.LoggerMessageFormat;
import org.elasticsearch.watcher.WatcherException;
/**
*
*/
public class ActionException extends WatcherException {
public ActionException(String msg, Object... args) {
super(LoggerMessageFormat.format(msg, args));
}
public ActionException(String msg, Throwable cause, Object... args) {
super(LoggerMessageFormat.format(msg, args), cause);
}
}

View File

@ -6,11 +6,12 @@
package org.elasticsearch.watcher.actions;
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.license.LicenseService;
import org.elasticsearch.watcher.support.validation.Validation;
import org.elasticsearch.watcher.support.clock.Clock;
import org.elasticsearch.watcher.support.validation.Validation;
import org.elasticsearch.watcher.transform.TransformRegistry;
import java.io.IOException;
@ -41,7 +42,7 @@ public class ActionRegistry {
public ExecutableActions parseActions(String watchId, XContentParser parser) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
throw new ActionException("could not parse actions for watch [{}]. expected an object but found [{}] instead", watchId, parser.currentToken());
throw new ElasticsearchParseException("could not parse actions for watch [{}]. expected an object but found [{}] instead", watchId, parser.currentToken());
}
List<ActionWrapper> actions = new ArrayList<>();
@ -52,7 +53,7 @@ public class ActionRegistry {
id = parser.currentName();
Validation.Error error = Validation.actionId(id);
if (error != null) {
throw new ActionException("could not parse action [{}] for watch [{}]. {}", id, watchId, error);
throw new ElasticsearchParseException("could not parse action [{}] for watch [{}]. {}", id, watchId, error);
}
} else if (token == XContentParser.Token.START_OBJECT && id != null) {
ActionWrapper action = ActionWrapper.parse(watchId, id, parser, this, transformRegistry, clock, licenseService);

View File

@ -1,20 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.actions;
/**
*
*/
public class ActionSettingsException extends ActionException {
public ActionSettingsException(String msg) {
super(msg);
}
public ActionSettingsException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.actions;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
@ -13,13 +14,13 @@ import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.WatcherException;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import java.io.IOException;
import java.util.Locale;
import static org.elasticsearch.watcher.support.Exceptions.illegalArgument;
import static org.elasticsearch.watcher.support.WatcherDateTimeUtils.dateTimeFormatter;
/**
@ -183,11 +184,11 @@ public class ActionStatus implements ToXContent {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.LAST_THROTTLE)) {
lastThrottle = Throttle.parse(watchId, actionId, parser);
} else {
throw new ParseException("could not parse action status for [{}/{}]. unexpected field [{}]", watchId, actionId, currentFieldName);
throw new ElasticsearchParseException("could not parse action status for [{}/{}]. unexpected field [{}]", watchId, actionId, currentFieldName);
}
}
if (ackStatus == null) {
throw new ParseException("could not parse action status for [{}/{}]. missing required field [{}]", watchId, actionId, Field.ACK_STATUS.getPreferredName());
throw new ElasticsearchParseException("could not parse action status for [{}/{}]. missing required field [{}]", watchId, actionId, Field.ACK_STATUS.getPreferredName());
}
return new ActionStatus(ackStatus, lastExecution, lastSuccessfulExecution, lastThrottle);
}
@ -211,7 +212,7 @@ public class ActionStatus implements ToXContent {
case 2 : return ACKABLE;
case 3 : return ACKED;
default:
throw new WatcherException("unknown action ack status state value [{}]", value);
throw illegalArgument("unknown action ack status state value [{}]", value);
}
}
}
@ -272,14 +273,14 @@ public class ActionStatus implements ToXContent {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.ACK_STATUS_STATE)) {
state = State.valueOf(parser.text().toUpperCase(Locale.ROOT));
} else {
throw new ParseException("could not parse action status for [{}/{}]. unexpected field [{}.{}]", watchId, actionId, Field.ACK_STATUS.getPreferredName(), currentFieldName);
throw new ElasticsearchParseException("could not parse action status for [{}/{}]. unexpected field [{}.{}]", watchId, actionId, Field.ACK_STATUS.getPreferredName(), currentFieldName);
}
}
if (timestamp == null) {
throw new ParseException("could not parse action status for [{}/{}]. missing required field [{}.{}]", watchId, actionId, Field.ACK_STATUS.getPreferredName(), Field.TIMESTAMP.getPreferredName());
throw new ElasticsearchParseException("could not parse action status for [{}/{}]. missing required field [{}.{}]", watchId, actionId, Field.ACK_STATUS.getPreferredName(), Field.TIMESTAMP.getPreferredName());
}
if (state == null) {
throw new ParseException("could not parse action status for [{}/{}]. missing required field [{}.{}]", watchId, actionId, Field.ACK_STATUS.getPreferredName(), Field.ACK_STATUS_STATE.getPreferredName());
throw new ElasticsearchParseException("could not parse action status for [{}/{}]. missing required field [{}.{}]", watchId, actionId, Field.ACK_STATUS.getPreferredName(), Field.ACK_STATUS_STATE.getPreferredName());
}
return new AckStatus(timestamp, state);
}
@ -377,20 +378,20 @@ public class ActionStatus implements ToXContent {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.REASON)) {
reason = parser.text();
} else {
throw new ParseException("could not parse action status for [{}/{}]. unexpected field [{}.{}]", watchId, actionId, Field.LAST_EXECUTION.getPreferredName(), currentFieldName);
throw new ElasticsearchParseException("could not parse action status for [{}/{}]. unexpected field [{}.{}]", watchId, actionId, Field.LAST_EXECUTION.getPreferredName(), currentFieldName);
}
}
if (timestamp == null) {
throw new ParseException("could not parse action status for [{}/{}]. missing required field [{}.{}]", watchId, actionId, Field.LAST_EXECUTION.getPreferredName(), Field.TIMESTAMP.getPreferredName());
throw new ElasticsearchParseException("could not parse action status for [{}/{}]. missing required field [{}.{}]", watchId, actionId, Field.LAST_EXECUTION.getPreferredName(), Field.TIMESTAMP.getPreferredName());
}
if (successful == null) {
throw new ParseException("could not parse action status for [{}/{}]. missing required field [{}.{}]", watchId, actionId, Field.LAST_EXECUTION.getPreferredName(), Field.EXECUTION_SUCCESSFUL.getPreferredName());
throw new ElasticsearchParseException("could not parse action status for [{}/{}]. missing required field [{}.{}]", watchId, actionId, Field.LAST_EXECUTION.getPreferredName(), Field.EXECUTION_SUCCESSFUL.getPreferredName());
}
if (successful) {
return successful(timestamp);
}
if (reason == null) {
throw new ParseException("could not parse action status for [{}/{}]. missing required field for unsuccessful execution [{}.{}]", watchId, actionId, Field.LAST_EXECUTION.getPreferredName(), Field.REASON.getPreferredName());
throw new ElasticsearchParseException("could not parse action status for [{}/{}]. missing required field for unsuccessful execution [{}.{}]", watchId, actionId, Field.LAST_EXECUTION.getPreferredName(), Field.REASON.getPreferredName());
}
return failure(timestamp, reason);
}
@ -471,14 +472,14 @@ public class ActionStatus implements ToXContent {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.REASON)) {
reason = parser.text();
} else {
throw new ParseException("could not parse action status for [{}/{}]. unexpected field [{}.{}]", watchId, actionId, Field.LAST_THROTTLE.getPreferredName(), currentFieldName);
throw new ElasticsearchParseException("could not parse action status for [{}/{}]. unexpected field [{}.{}]", watchId, actionId, Field.LAST_THROTTLE.getPreferredName(), currentFieldName);
}
}
if (timestamp == null) {
throw new ParseException("could not parse action status for [{}/{}]. missing required field [{}.{}]", watchId, actionId, Field.LAST_THROTTLE.getPreferredName(), Field.TIMESTAMP.getPreferredName());
throw new ElasticsearchParseException("could not parse action status for [{}/{}]. missing required field [{}.{}]", watchId, actionId, Field.LAST_THROTTLE.getPreferredName(), Field.TIMESTAMP.getPreferredName());
}
if (reason == null) {
throw new ParseException("could not parse action status for [{}/{}]. missing required field [{}.{}]", watchId, actionId, Field.LAST_THROTTLE.getPreferredName(), Field.REASON.getPreferredName());
throw new ElasticsearchParseException("could not parse action status for [{}/{}]. missing required field [{}.{}]", watchId, actionId, Field.LAST_THROTTLE.getPreferredName(), Field.REASON.getPreferredName());
}
return new Throttle(timestamp, reason);
}
@ -494,17 +495,6 @@ public class ActionStatus implements ToXContent {
}
}
static class ParseException extends WatcherException {
public ParseException(String msg, Object... args) {
super(msg, args);
}
public ParseException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}
interface Field {
ParseField ACK_STATUS = new ParseField("ack");
ParseField ACK_STATUS_STATE = new ParseField("state");

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.actions;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
@ -155,21 +156,21 @@ public class ActionWrapper implements ToXContent {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Throttler.Field.THROTTLE_PERIOD)) {
try {
throttlePeriod = WatcherDateTimeUtils.parseTimeValue(parser, Throttler.Field.THROTTLE_PERIOD.toString());
} catch (WatcherDateTimeUtils.ParseException pe) {
throw new ActionException("could not parse action [{}/{}]. failed to parse field [{}] as time value", pe, watchId, actionId, currentFieldName);
} catch (ElasticsearchParseException pe) {
throw new ElasticsearchParseException("could not parse action [{}/{}]. failed to parse field [{}] as time value", pe, watchId, actionId, currentFieldName);
}
} else {
// it's the type of the action
ActionFactory actionFactory = actionRegistry.factory(currentFieldName);
if (actionFactory == null) {
throw new ActionException("could not parse action [{}/{}]. unknown action type [{}]", watchId, actionId, currentFieldName);
throw new ElasticsearchParseException("could not parse action [{}/{}]. unknown action type [{}]", watchId, actionId, currentFieldName);
}
action = actionFactory.parseExecutable(watchId, actionId, parser);
}
}
}
if (action == null) {
throw new ActionException("could not parse watch action [{}/{}]. missing action type", watchId, actionId);
throw new ElasticsearchParseException("could not parse watch action [{}/{}]. missing action type", watchId, actionId);
}
ActionThrottler throttler = new ActionThrottler(clock, throttlePeriod, licenseService);

View File

@ -5,13 +5,13 @@
*/
package org.elasticsearch.watcher.actions.email;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.actions.email.service.Attachment;
import org.elasticsearch.watcher.watch.Payload;
@ -19,6 +19,8 @@ import java.io.IOException;
import java.util.Locale;
import java.util.Map;
import static org.elasticsearch.watcher.support.Exceptions.illegalArgument;
/**
*
*/
@ -69,7 +71,7 @@ public enum DataAttachment implements ToXContent {
case "yaml": return YAML;
case "json": return JSON;
default:
throw new Exception("unknown data attachment format [{}]", format);
throw illegalArgument("unknown data attachment format [{}]", format);
}
}
@ -82,7 +84,7 @@ public enum DataAttachment implements ToXContent {
return parser.booleanValue() ? DEFAULT : null;
}
if (token != XContentParser.Token.START_OBJECT) {
throw new Exception("could not parse data attachment. expected either a boolean value or an object but found [{}] instead", token);
throw new ElasticsearchParseException("could not parse data attachment. expected either a boolean value or an object but found [{}] instead", token);
}
DataAttachment dataAttachment = DEFAULT;
@ -92,32 +94,21 @@ public enum DataAttachment implements ToXContent {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (currentFieldName == null) {
throw new Exception("could not parse data attachment. expected [{}] field but found [{}] instead", Field.FORMAT.getPreferredName(), token);
throw new ElasticsearchParseException("could not parse data attachment. expected [{}] field but found [{}] instead", Field.FORMAT.getPreferredName(), token);
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.FORMAT)) {
if (token == XContentParser.Token.VALUE_STRING) {
dataAttachment = resolve(parser.text());
} else {
throw new Exception("could not parse data attachment. expected string value for [{}] field but found [{}] instead", currentFieldName, token);
throw new ElasticsearchParseException("could not parse data attachment. expected string value for [{}] field but found [{}] instead", currentFieldName, token);
}
} else {
throw new Exception("could not parse data attachment. unexpected field [{}]", currentFieldName);
throw new ElasticsearchParseException("could not parse data attachment. unexpected field [{}]", currentFieldName);
}
}
return dataAttachment;
}
public static class Exception extends WatcherException {
public Exception(String msg, Object... args) {
super(msg, args);
}
public Exception(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}
interface Field {
ParseField FORMAT = new ParseField("format");
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.actions.email;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
@ -130,8 +131,8 @@ public class EmailAction implements Action {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.ATTACH_DATA)) {
try {
dataAttachment = DataAttachment.parse(parser);
} catch (DataAttachment.Exception dae) {
throw new EmailActionException("could not parse [{}] action [{}/{}]. failed to parse data attachment field [{}]", dae, TYPE, watchId, actionId, currentFieldName);
} catch (IOException ioe) {
throw new ElasticsearchParseException("could not parse [{}] action [{}/{}]. failed to parse data attachment field [{}]", ioe, TYPE, watchId, actionId, currentFieldName);
}
}else if (!emailParser.handle(currentFieldName, parser)) {
if (token == XContentParser.Token.VALUE_STRING) {
@ -142,12 +143,16 @@ public class EmailAction implements Action {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.PASSWORD)) {
password = SensitiveXContentParser.secretOrNull(parser);
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.PROFILE)) {
profile = Profile.resolve(parser.text());
try {
profile = Profile.resolve(parser.text());
} catch (IllegalArgumentException iae) {
throw new ElasticsearchParseException("could not parse [{}] action [{}/{}]", TYPE, watchId, actionId, iae);
}
} else {
throw new EmailActionException("could not parse [{}] action [{}/{}]. unexpected string field [{}]", TYPE, watchId, actionId, currentFieldName);
throw new ElasticsearchParseException("could not parse [{}] action [{}/{}]. unexpected string field [{}]", TYPE, watchId, actionId, currentFieldName);
}
} else {
throw new EmailActionException("could not parse [{}] action [{}/{}]. unexpected token [{}]", TYPE, watchId, actionId, token);
throw new ElasticsearchParseException("could not parse [{}] action [{}/{}]. unexpected token [{}]", TYPE, watchId, actionId, token);
}
}
}

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.actions.email;
import org.elasticsearch.watcher.actions.ActionException;
/**
*
*/
public class EmailActionException extends ActionException {
public EmailActionException(String msg, Object... args) {
super(msg, args);
}
public EmailActionException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -7,7 +7,7 @@ package org.elasticsearch.watcher.actions.email.service;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.watcher.support.secret.SecretService;
import javax.activation.CommandMap;
@ -60,7 +60,7 @@ public class Account {
email = config.defaults.apply(email);
if (email.to == null) {
throw new EmailException("email must have [to] recipient");
throw new SettingsException("missing required email [to] field");
}
Transport transport = session.getTransport(SMTP_PROTOCOL);
@ -117,10 +117,10 @@ public class Account {
public Config(String name, Settings settings) {
this.name = name;
profile = Profile.resolve(settings.get("profile"), Profile.STANDARD);
defaults = new EmailDefaults(settings.getAsSettings("email_defaults"));
defaults = new EmailDefaults(name, settings.getAsSettings("email_defaults"));
smtp = new Smtp(settings.getAsSettings(SMTP_PROTOCOL));
if (smtp.host == null) {
throw new EmailSettingsException("missing required email account setting for account [" + name + "]. 'smtp.host' must be configured");
throw new SettingsException("missing required email account setting for account [" + name + "]. 'smtp.host' must be configured");
}
}
@ -200,14 +200,18 @@ public class Account {
final Email.AddressList bcc;
final String subject;
public EmailDefaults(Settings settings) {
from = Email.Address.parse(settings, Email.Field.FROM.getPreferredName());
replyTo = Email.AddressList.parse(settings, Email.Field.REPLY_TO.getPreferredName());
priority = Email.Priority.parse(settings, Email.Field.PRIORITY.getPreferredName());
to = Email.AddressList.parse(settings, Email.Field.TO.getPreferredName());
cc = Email.AddressList.parse(settings, Email.Field.CC.getPreferredName());
bcc = Email.AddressList.parse(settings, Email.Field.BCC.getPreferredName());
subject = settings.get(Email.Field.SUBJECT.getPreferredName());
public EmailDefaults(String accountName, Settings settings) {
try {
from = Email.Address.parse(settings, Email.Field.FROM.getPreferredName());
replyTo = Email.AddressList.parse(settings, Email.Field.REPLY_TO.getPreferredName());
priority = Email.Priority.parse(settings, Email.Field.PRIORITY.getPreferredName());
to = Email.AddressList.parse(settings, Email.Field.TO.getPreferredName());
cc = Email.AddressList.parse(settings, Email.Field.CC.getPreferredName());
bcc = Email.AddressList.parse(settings, Email.Field.BCC.getPreferredName());
subject = settings.get(Email.Field.SUBJECT.getPreferredName());
} catch (IllegalArgumentException iae) {
throw new SettingsException("invalid email defaults in email account settings [" + accountName + "]", iae);
}
}
Email apply(Email email) {

View File

@ -7,6 +7,7 @@ package org.elasticsearch.watcher.actions.email.service;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.watcher.support.secret.SecretService;
import java.util.HashMap;
@ -39,7 +40,7 @@ public class Accounts {
this.defaultAccountName = account.name();
}
} else if (!accounts.containsKey(defaultAccountName)) {
throw new EmailSettingsException("could not fine default account [" + defaultAccountName + "]");
throw new SettingsException("could not find default email account [" + defaultAccountName + "]");
} else {
this.defaultAccountName = defaultAccountName;
}
@ -51,12 +52,12 @@ public class Accounts {
*
* @param name The name of the requested account
* @return The account associated with the given name.
* @throws EmailException if the name is null and the default account is null.
* @throws IllegalStateException if the name is null and the default account is null.
*/
public Account account(String name) throws EmailException {
public Account account(String name) throws IllegalStateException {
if (name == null) {
if (defaultAccountName == null) {
throw new EmailSettingsException("cannot find default email account as no accounts have been configured");
throw new IllegalStateException("cannot find default email account as no accounts have been configured");
}
name = defaultAccountName;
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.actions.email.service;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.watcher.actions.email.service.support.BodyPartSource;
import org.elasticsearch.common.xcontent.ToXContent;
@ -150,7 +151,7 @@ public abstract class Attachment extends BodyPartSource {
case SMILE: return "application/smile";
case CBOR: return "application/cbor";
default:
throw new EmailException("unsupported xcontent attachment type [" + type.name() + "]");
throw new IllegalArgumentException("unsupported xcontent attachment type [" + type.name() + "]");
}
}
@ -160,7 +161,7 @@ public abstract class Attachment extends BodyPartSource {
content.toXContent(builder, ToXContent.EMPTY_PARAMS);
return builder.bytes().toBytes();
} catch (IOException ioe) {
throw new EmailException("could not create an xcontent attachment [" + name + "]", ioe);
throw new ElasticsearchException("could not create an xcontent attachment [" + name + "]", ioe);
}
}

View File

@ -6,13 +6,15 @@
package org.elasticsearch.watcher.actions.email.service;
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
import org.joda.time.DateTime;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import javax.mail.MessagingException;
@ -207,18 +209,18 @@ public class Email implements ToXContent {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (currentFieldName == null) {
throw new ParseException("could not parse email. empty [{}] field", bodyField);
throw new ElasticsearchParseException("could not parse email. empty [{}] field", bodyField);
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Email.Field.BODY_TEXT)) {
email.textBody(parser.text());
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Email.Field.BODY_HTML)) {
email.htmlBody(parser.text());
} else {
throw new ParseException("could not parse email. unexpected field [{}.{}] field", bodyField, currentFieldName);
throw new ElasticsearchParseException("could not parse email. unexpected field [{}.{}] field", bodyField, currentFieldName);
}
}
}
} else {
throw new ParseException("could not parse email. unexpected field [{}]", currentFieldName);
throw new ElasticsearchParseException("could not parse email. unexpected field [{}]", currentFieldName);
}
}
}
@ -387,7 +389,7 @@ public class Email implements ToXContent {
public static Priority resolve(String name) {
Priority priority = resolve(name, null);
if (priority == null) {
throw new EmailSettingsException("unknown email priority [" + name + "]");
throw new IllegalArgumentException("[" + name + "] is not a valid email priority");
}
return priority;
}
@ -440,7 +442,7 @@ public class Email implements ToXContent {
try {
return new Email.Address(parser.text());
} catch (AddressException ae) {
throw new ParseException("could not parse [" + text + "] in field [" + field + "] as address. address must be RFC822 encoded", ae);
throw new ElasticsearchParseException("could not parse [" + text + "] in field [" + field + "] as address. address must be RFC822 encoded", ae);
}
}
@ -457,21 +459,21 @@ public class Email implements ToXContent {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, ADDRESS_NAME_FIELD)) {
name = parser.text();
} else {
throw new ParseException("could not parse [" + field + "] object as address. unknown address field [" + currentFieldName + "]");
throw new ElasticsearchParseException("could not parse [" + field + "] object as address. unknown address field [" + currentFieldName + "]");
}
}
}
if (email == null) {
throw new ParseException("could not parse [" + field + "] as address. address object must define an [email] field");
throw new ElasticsearchParseException("could not parse [" + field + "] as address. address object must define an [email] field");
}
try {
return name != null ? new Email.Address(email, name) : new Email.Address(email);
} catch (AddressException ae) {
throw new ParseException("could not parse [" + field + "] as address", ae);
throw new ElasticsearchParseException("could not parse [" + field + "] as address", ae);
}
}
throw new ParseException("could not parse [" + field + "] as address. address must either be a string (RFC822 encoded) or an object specifying the address [name] and [email]");
throw new ElasticsearchParseException("could not parse [{}] as address. address must either be a string (RFC822 encoded) or an object specifying the address [name] and [email]", field);
}
public static Address parse(Settings settings, String name) {
@ -479,7 +481,7 @@ public class Email implements ToXContent {
try {
return value != null ? new Address(value) : null;
} catch (AddressException ae) {
throw new EmailSettingsException("could not parse [" + value + "] as a RFC822 email address", ae);
throw new IllegalArgumentException("[" + value + "] is not a valid RFC822 email address", ae);
}
}
}
@ -541,7 +543,7 @@ public class Email implements ToXContent {
}
return new AddressList(list);
} catch (AddressException ae) {
throw new EmailSettingsException("could not parse [" + settings.get(name) + "] as a list of RFC822 email address", ae);
throw new IllegalArgumentException("[" + settings.get(name) + "] is not a valid list of RFC822 email addresses", ae);
}
}
@ -551,7 +553,7 @@ public class Email implements ToXContent {
try {
return parse(parser.text());
} catch (AddressException ae) {
throw new ParseException("could not parse field [" + field + "] with value [" + text + "] as address list. address(es) must be RFC822 encoded", ae);
throw new ElasticsearchParseException("could not parse field [" + field + "] with value [" + text + "] as address list. address(es) must be RFC822 encoded", ae);
}
}
if (token == XContentParser.Token.START_ARRAY) {
@ -561,7 +563,7 @@ public class Email implements ToXContent {
}
return new Email.AddressList(addresses);
}
throw new ParseException("could not parse [" + field + "] as address list. field must either be a string " +
throw new ElasticsearchParseException("could not parse [" + field + "] as address list. field must either be a string " +
"(comma-separated list of RFC822 encoded addresses) or an array of objects representing addresses");
}
@ -583,17 +585,6 @@ public class Email implements ToXContent {
}
}
public static class ParseException extends EmailException {
public ParseException(String msg, Object... args) {
super(msg, args);
}
public ParseException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}
interface Field {
ParseField ID = new ParseField("id");
ParseField FROM = new ParseField("from");

View File

@ -1,23 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.actions.email.service;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.actions.ActionException;
/**
*
*/
public class EmailException extends WatcherException {
public EmailException(String msg, Object... args) {
super(msg, args);
}
public EmailException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -5,16 +5,18 @@
*/
package org.elasticsearch.watcher.actions.email.service;
import javax.mail.MessagingException;
/**
*
*/
public interface EmailService {
EmailSent send(Email email, Authentication auth, Profile profile);
EmailSent send(Email email, Authentication auth, Profile profile) throws MessagingException;
EmailSent send(Email email, Authentication auth, Profile profile, String accountName);
EmailSent send(Email email, Authentication auth, Profile profile, String accountName) throws MessagingException;
static class EmailSent {
class EmailSent {
private final String account;
private final Email email;

View File

@ -1,20 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.actions.email.service;
/**
*
*/
public class EmailSettingsException extends EmailException {
public EmailSettingsException(String msg) {
super(msg);
}
public EmailSettingsException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@ -5,11 +5,11 @@
*/
package org.elasticsearch.watcher.actions.email.service;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.support.template.Template;
import org.elasticsearch.watcher.support.template.TemplateEngine;
@ -446,13 +446,13 @@ public class EmailTemplate implements ToXContent {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (currentFieldName == null) {
throw new ParseException("could not parse email template. empty [{}] field", fieldName);
throw new ElasticsearchParseException("could not parse email template. empty [{}] field", fieldName);
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Email.Field.BODY_TEXT)) {
builder.textBody(Template.parse(parser));
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Email.Field.BODY_HTML)) {
builder.htmlBody(Template.parse(parser));
} else {
throw new ParseException("could not parse email template. unknown field [{}.{}] field", fieldName, currentFieldName);
throw new ElasticsearchParseException("could not parse email template. unknown field [{}.{}] field", fieldName, currentFieldName);
}
}
}
@ -467,16 +467,4 @@ public class EmailTemplate implements ToXContent {
}
}
public static class ParseException extends WatcherException {
public ParseException(String msg, Object... args) {
super(msg, args);
}
public ParseException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}
}

View File

@ -5,13 +5,11 @@
*/
package org.elasticsearch.watcher.actions.email.service;
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.node.settings.NodeSettingsService;
import org.elasticsearch.watcher.shield.WatcherSettingsFilter;
import org.elasticsearch.watcher.support.secret.SecretService;
@ -54,25 +52,25 @@ public class InternalEmailService extends AbstractLifecycleComponent<InternalEma
}
@Override
public EmailSent send(Email email, Authentication auth, Profile profile) {
public EmailSent send(Email email, Authentication auth, Profile profile) throws MessagingException {
return send(email, auth, profile, (String) null);
}
@Override
public EmailSent send(Email email, Authentication auth, Profile profile, String accountName) {
public EmailSent send(Email email, Authentication auth, Profile profile, String accountName) throws MessagingException {
Account account = accounts.account(accountName);
if (account == null) {
throw new EmailException("failed to send email with subject [" + email.subject() + "] via account [" + accountName + "]. account does not exist");
throw new IllegalArgumentException("failed to send email with subject [" + email.subject() + "] via account [" + accountName + "]. account does not exist");
}
return send(email, auth, profile, account);
}
EmailSent send(Email email, Authentication auth, Profile profile, Account account) {
EmailSent send(Email email, Authentication auth, Profile profile, Account account) throws MessagingException {
assert account != null;
try {
email = account.send(email, auth, profile);
} catch (MessagingException me) {
throw new EmailException("failed to send email with subject [" + email.subject() + "] via account [" + account.name() + "]", me);
throw new MessagingException("failed to send email with subject [" + email.subject() + "] via account [" + account.name() + "]", me);
}
return new EmailSent(account.name(), email);
}

View File

@ -32,14 +32,13 @@ public enum Profile implements ToXContent {
MimeMultipart related = null;
for (int i = 0; i < mixed.getCount(); i++) {
MimeBodyPart part = (MimeBodyPart) mixed.getBodyPart(i);
if (part.getContentType().startsWith("multipart/related")) {
related = (MimeMultipart) part.getContent();
break;
}
}
if (related == null) {
throw new EmailException("could not extract body text from mime message");
throw new IllegalStateException("could not extract body text from mime message using [standard] profile. could not find part content type with [multipart/related]");
}
MimeMultipart alternative = null;
@ -51,7 +50,7 @@ public enum Profile implements ToXContent {
}
}
if (alternative == null) {
throw new EmailException("could not extract body text from mime message");
throw new IllegalStateException("could not extract body text from mime message using [standard] profile. could not find part content type with [multipart/alternative]");
}
for (int i = 0; i < alternative.getCount(); i++) {
@ -61,7 +60,7 @@ public enum Profile implements ToXContent {
}
}
throw new EmailException("could not extract body text from mime message");
throw new IllegalStateException("could not extract body text from mime message using [standard] profile");
}
@Override
@ -153,7 +152,7 @@ public enum Profile implements ToXContent {
public static Profile resolve(String name) {
Profile profile = resolve(name, null);
if (profile == null) {
throw new EmailSettingsException("unsupported email profile [" + name + "]");
throw new IllegalArgumentException("[" + name + "] is an unknown email profile");
}
return profile;
}

View File

@ -31,6 +31,7 @@ import java.util.HashMap;
import java.util.Map;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.watcher.support.Exceptions.illegalState;
public class ExecutableIndexAction extends ExecutableAction<IndexAction> {
@ -63,7 +64,8 @@ public class ExecutableIndexAction extends ExecutableAction<IndexAction> {
if (doc instanceof Map) {
data = (Map<String, Object>) doc;
} else {
throw new IndexActionException("could not execute action [{}] of watch [{}]. failed to index payload data. [_data] field must either hold a Map or an List/Array of Maps", actionId, ctx.watch().id());
throw illegalState("could not execute action [{}] of watch [{}]. failed to index payload data." +
"[_data] field must either hold a Map or an List/Array of Maps", actionId, ctx.watch().id());
}
}
@ -97,7 +99,8 @@ public class ExecutableIndexAction extends ExecutableAction<IndexAction> {
BulkRequest bulkRequest = new BulkRequest();
for (Object item : list) {
if (!(item instanceof Map)) {
throw new IndexActionException("could not execute action [{}] of watch [{}]. failed to index payload data. [_data] field must either hold a Map or an List/Array of Maps", actionId, ctx.watch().id());
throw illegalState("could not execute action [{}] of watch [{}]. failed to index payload data. " +
"[_data] field must either hold a Map or an List/Array of Maps", actionId, ctx.watch().id());
}
Map<String, Object> doc = (Map<String, Object>) item;
IndexRequest indexRequest = new IndexRequest();

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.actions.index;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
@ -12,7 +13,6 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.actions.Action;
import org.elasticsearch.watcher.support.DynamicIndexName;
import org.elasticsearch.watcher.support.WatcherDateTimeUtils;
import org.elasticsearch.watcher.support.xcontent.XContentSource;
import org.joda.time.DateTimeZone;
@ -119,8 +119,8 @@ public class IndexAction implements Action {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.INDEX)) {
try {
index = parser.text();
} catch (DynamicIndexName.ParseException pe) {
throw new IndexActionException("could not parse [{}] action [{}/{}]. failed to parse index name value for field [{}]", pe, TYPE, watchId, actionId, currentFieldName);
} catch (ElasticsearchParseException pe) {
throw new ElasticsearchParseException("could not parse [{}] action [{}/{}]. failed to parse index name value for field [{}]", pe, TYPE, watchId, actionId, currentFieldName);
}
} else if (token == XContentParser.Token.VALUE_STRING) {
if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.DOC_TYPE)) {
@ -133,22 +133,22 @@ public class IndexAction implements Action {
if (token == XContentParser.Token.VALUE_STRING) {
dynamicNameTimeZone = DateTimeZone.forID(parser.text());
} else {
throw new IndexActionException("could not parse [{}] action for watch [{}]. failed to parse [{}]. must be a string value (e.g. 'UTC' or '+01:00').", TYPE, watchId, currentFieldName);
throw new ElasticsearchParseException("could not parse [{}] action for watch [{}]. failed to parse [{}]. must be a string value (e.g. 'UTC' or '+01:00').", TYPE, watchId, currentFieldName);
}
} else {
throw new IndexActionException("could not parse [{}] action [{}/{}]. unexpected string field [{}]", TYPE, watchId, actionId, currentFieldName);
throw new ElasticsearchParseException("could not parse [{}] action [{}/{}]. unexpected string field [{}]", TYPE, watchId, actionId, currentFieldName);
}
} else {
throw new IndexActionException("could not parse [{}] action [{}/{}]. unexpected token [{}]", TYPE, watchId, actionId, token);
throw new ElasticsearchParseException("could not parse [{}] action [{}/{}]. unexpected token [{}]", TYPE, watchId, actionId, token);
}
}
if (index == null) {
throw new IndexActionException("could not parse [{}] action [{}/{}]. missing required [{}] field", TYPE, watchId, actionId, Field.INDEX.getPreferredName());
throw new ElasticsearchParseException("could not parse [{}] action [{}/{}]. missing required [{}] field", TYPE, watchId, actionId, Field.INDEX.getPreferredName());
}
if (docType == null) {
throw new IndexActionException("could not parse [{}] action [{}/{}]. missing required [{}] field", TYPE, watchId, actionId, Field.DOC_TYPE.getPreferredName());
throw new ElasticsearchParseException("could not parse [{}] action [{}/{}]. missing required [{}] field", TYPE, watchId, actionId, Field.DOC_TYPE.getPreferredName());
}
return new IndexAction(index, docType, executionTimeField, timeout, dynamicNameTimeZone);

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.actions.index;
import org.elasticsearch.watcher.actions.ActionException;
/**
*
*/
public class IndexActionException extends ActionException {
public IndexActionException(String msg, Object... args) {
super(msg, args);
}
public IndexActionException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.actions.logging;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
@ -82,8 +83,8 @@ public class LoggingAction implements Action {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.TEXT)) {
try {
text = Template.parse(parser);
} catch (Template.ParseException pe) {
throw new LoggingActionException("failed to parse [{}] action [{}/{}]. failed to parse [{}] field", pe, TYPE, watchId, actionId, Field.TEXT.getPreferredName());
} catch (ElasticsearchParseException pe) {
throw new ElasticsearchParseException("failed to parse [{}] action [{}/{}]. failed to parse [{}] field", pe, TYPE, watchId, actionId, Field.TEXT.getPreferredName());
}
} else if (token == XContentParser.Token.VALUE_STRING) {
if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.CATEGORY)) {
@ -92,18 +93,18 @@ public class LoggingAction implements Action {
try {
level = LoggingLevel.valueOf(parser.text().toUpperCase(Locale.ROOT));
} catch (IllegalArgumentException iae) {
throw new LoggingActionException("failed to parse [{}] action [{}/{}]. unknown logging level [{}]", TYPE, watchId, actionId, parser.text());
throw new ElasticsearchParseException("failed to parse [{}] action [{}/{}]. unknown logging level [{}]", TYPE, watchId, actionId, parser.text());
}
} else {
throw new LoggingActionException("failed to parse [{}] action [{}/{}]. unexpected string field [{}]", TYPE, watchId, actionId, currentFieldName);
throw new ElasticsearchParseException("failed to parse [{}] action [{}/{}]. unexpected string field [{}]", TYPE, watchId, actionId, currentFieldName);
}
} else {
throw new LoggingActionException("failed to parse [{}] action [{}/{}]. unexpected token [{}]", TYPE, watchId, actionId, token);
throw new ElasticsearchParseException("failed to parse [{}] action [{}/{}]. unexpected token [{}]", TYPE, watchId, actionId, token);
}
}
if (text == null) {
throw new LoggingActionException("failed to parse [{}] action [{}/{}]. missing required [{}] field", TYPE, watchId, actionId, Field.TEXT.getPreferredName());
throw new ElasticsearchParseException("failed to parse [{}] action [{}/{}]. missing required [{}] field", TYPE, watchId, actionId, Field.TEXT.getPreferredName());
}
return new LoggingAction(text, level, category);

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.actions.logging;
import org.elasticsearch.watcher.actions.ActionException;
/**
*
*/
public class LoggingActionException extends ActionException {
public LoggingActionException(String msg, Object... args) {
super(msg, args);
}
public LoggingActionException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.actions.webhook;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
@ -61,8 +62,8 @@ public class WebhookAction implements Action {
try {
HttpRequestTemplate request = requestParser.parse(parser);
return new WebhookAction(request);
} catch (HttpRequestTemplate.ParseException pe) {
throw new WebhookActionException("could not parse [{}] action [{}/{}]. failed parsing http request template", pe, TYPE, watchId, actionId);
} catch (ElasticsearchParseException pe) {
throw new ElasticsearchParseException("could not parse [{}] action [{}/{}]. failed parsing http request template", pe, TYPE, watchId, actionId);
}
}

View File

@ -1,23 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.actions.webhook;
import org.elasticsearch.common.logging.support.LoggerMessageFormat;
import org.elasticsearch.watcher.actions.ActionException;
/**
*
*/
public class WebhookActionException extends ActionException {
public WebhookActionException(String msg, Object... args) {
super(LoggerMessageFormat.format(msg, args));
}
public WebhookActionException(String msg, Throwable cause, Object... args) {
super(LoggerMessageFormat.format(msg, args), cause);
}
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.client;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.unit.TimeValue;
@ -12,14 +13,13 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.search.builder.SearchSourceBuilderException;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.actions.Action;
import org.elasticsearch.watcher.actions.throttler.Throttler;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.condition.always.AlwaysCondition;
import org.elasticsearch.watcher.input.Input;
import org.elasticsearch.watcher.input.none.NoneInput;
import org.elasticsearch.watcher.support.Exceptions;
import org.elasticsearch.watcher.support.xcontent.XContentSource;
import org.elasticsearch.watcher.transform.Transform;
import org.elasticsearch.watcher.trigger.Trigger;
@ -120,7 +120,7 @@ public class WatchSourceBuilder implements ToXContent {
builder.startObject();
if (trigger == null) {
throw new BuilderException("failed to build watch source. no trigger defined");
throw Exceptions.illegalState("failed to build watch source. no trigger defined");
}
builder.startObject(Watch.Field.TRIGGER.getPreferredName())
.field(trigger.type(), trigger, params)
@ -157,13 +157,14 @@ public class WatchSourceBuilder implements ToXContent {
return builder.endObject();
}
public BytesReference buildAsBytes(XContentType contentType) throws SearchSourceBuilderException {
public BytesReference buildAsBytes(XContentType contentType) {
try {
XContentBuilder builder = XContentFactory.contentBuilder(contentType);
toXContent(builder, ToXContent.EMPTY_PARAMS);
return builder.bytes();
} catch (java.lang.Exception e) {
throw new BuilderException("Failed to build watch source", e);
} catch (IOException ioe) {
// todo think of a better std exception for this
throw new ElasticsearchException("failed to render watch source as bytes", ioe);
}
}
@ -196,16 +197,4 @@ public class WatchSourceBuilder implements ToXContent {
return builder.endObject();
}
}
public static class BuilderException extends WatcherException {
public BuilderException(String msg) {
super(msg);
}
public BuilderException(String msg, Throwable cause) {
super(msg, cause);
}
}
}

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.condition;
import org.elasticsearch.watcher.WatcherException;
/**
*
*/
public class ConditionException extends WatcherException {
public ConditionException(String msg, Object... args) {
super(msg, args);
}
public ConditionException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -6,6 +6,7 @@
package org.elasticsearch.watcher.condition;
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -66,17 +67,17 @@ public class ConditionRegistry {
if (token == XContentParser.Token.FIELD_NAME) {
type = parser.currentName();
} else if (type == null) {
throw new ConditionException("could not parse condition for watch [{}]. invalid definition. expected a field indicating the condition type, but found", watchId, token);
throw new ElasticsearchParseException("could not parse condition for watch [{}]. invalid definition. expected a field indicating the condition type, but found", watchId, token);
} else {
factory = factories.get(type);
if (factory == null) {
throw new ConditionException("could not parse condition for watch [{}]. unknown condition type [{}]", watchId, type);
throw new ElasticsearchParseException("could not parse condition for watch [{}]. unknown condition type [{}]", watchId, type);
}
condition = factory.parseCondition(watchId, parser);
}
}
if (condition == null) {
throw new ConditionException("could not parse condition for watch [{}]. missing required condition type field", watchId);
throw new ElasticsearchParseException("could not parse condition for watch [{}]. missing required condition type field", watchId);
}
return condition;
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.condition.always;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.condition.Condition;
@ -31,11 +32,11 @@ public class AlwaysCondition implements Condition {
public static AlwaysCondition parse(String watchId, XContentParser parser) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
throw new AlwaysConditionException("unable to parse [{}] condition for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
throw new ElasticsearchParseException("unable to parse [{}] condition for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
}
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.END_OBJECT) {
throw new AlwaysConditionException("unable to parse [{}] condition for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
throw new ElasticsearchParseException("unable to parse [{}] condition for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
}
return INSTANCE;
}

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.condition.always;
import org.elasticsearch.watcher.condition.ConditionException;
/**
*
*/
public class AlwaysConditionException extends ConditionException {
public AlwaysConditionException(String msg, Object... args) {
super(msg, args);
}
public AlwaysConditionException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -5,14 +5,15 @@
*/
package org.elasticsearch.watcher.condition.compare;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.joda.time.DateTime;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.support.WatcherDateTimeUtils;
import org.elasticsearch.watcher.support.xcontent.WatcherXContentUtils;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import java.io.IOException;
@ -85,7 +86,7 @@ public class CompareCondition implements Condition {
public static CompareCondition parse(String watchId, XContentParser parser) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
throw new CompareConditionException("could not parse [{}] condition for watch [{}]. expected an object but found [{}] instead", TYPE, watchId, parser.currentToken());
throw new ElasticsearchParseException("could not parse [{}] condition for watch [{}]. expected an object but found [{}] instead", TYPE, watchId, parser.currentToken());
}
String path = null;
Object value = null;
@ -96,28 +97,28 @@ public class CompareCondition implements Condition {
if (token == XContentParser.Token.FIELD_NAME) {
path = parser.currentName();
} else if (path == null) {
throw new CompareConditionException("could not parse [{}] condition for watch [{}]. expected a field indicating the compared path, but found [{}] instead", TYPE, watchId, token);
throw new ElasticsearchParseException("could not parse [{}] condition for watch [{}]. expected a field indicating the compared path, but found [{}] instead", TYPE, watchId, token);
} else if (token == XContentParser.Token.START_OBJECT) {
token = parser.nextToken();
if (token != XContentParser.Token.FIELD_NAME) {
throw new CompareConditionException("could not parse [{}] condition for watch [{}]. expected a field indicating the comparison operator, but found [{}] instead", TYPE, watchId, token);
throw new ElasticsearchParseException("could not parse [{}] condition for watch [{}]. expected a field indicating the comparison operator, but found [{}] instead", TYPE, watchId, token);
}
try {
op = Op.resolve(parser.currentName());
} catch (IllegalArgumentException iae) {
throw new CompareConditionException("could not parse [{}] condition for watch [{}]. unknown comparison operator [{}]", TYPE, watchId, parser.currentName());
throw new ElasticsearchParseException("could not parse [{}] condition for watch [{}]. unknown comparison operator [{}]", TYPE, watchId, parser.currentName());
}
token = parser.nextToken();
if (!op.supportsStructures() && !token.isValue() && token != XContentParser.Token.VALUE_NULL) {
throw new CompareConditionException("could not parse [{}] condition for watch [{}]. compared value for [{}] with operation [{}] must either be a numeric, string, boolean or null value, but found [{}] instead", TYPE, watchId, path, op.name().toLowerCase(Locale.ROOT), token);
throw new ElasticsearchParseException("could not parse [{}] condition for watch [{}]. compared value for [{}] with operation [{}] must either be a numeric, string, boolean or null value, but found [{}] instead", TYPE, watchId, path, op.name().toLowerCase(Locale.ROOT), token);
}
value = WatcherXContentUtils.readValue(parser, token);
token = parser.nextToken();
if (token != XContentParser.Token.END_OBJECT) {
throw new CompareConditionException("could not parse [{}] condition for watch [{}]. expected end of path object, but found [{}] instead", TYPE, watchId, token);
throw new ElasticsearchParseException("could not parse [{}] condition for watch [{}]. expected end of path object, but found [{}] instead", TYPE, watchId, token);
}
} else {
throw new CompareConditionException("could not parse [{}] condition for watch [{}]. expected an object for field [{}] but found [{}] instead", TYPE, watchId, path, token);
throw new ElasticsearchParseException("could not parse [{}] condition for watch [{}]. expected an object for field [{}] but found [{}] instead", TYPE, watchId, path, token);
}
}

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.condition.compare;
import org.elasticsearch.watcher.condition.ConditionException;
/**
*
*/
public class CompareConditionException extends ConditionException {
public CompareConditionException(String msg, Object... args) {
super(msg, args);
}
public CompareConditionException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.condition.never;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.condition.Condition;
@ -31,11 +32,11 @@ public class NeverCondition implements Condition {
public static NeverCondition parse(String watchId, XContentParser parser) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
throw new NeverConditionException("could not parse [{}] condition for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
throw new ElasticsearchParseException("could not parse [{}] condition for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
}
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.END_OBJECT) {
throw new NeverConditionException("could not parse [{}] condition for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
throw new ElasticsearchParseException("could not parse [{}] condition for watch [{}]. expected an empty object but found [{}]", TYPE, watchId, parser.currentName());
}
return INSTANCE;
}

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.condition.never;
import org.elasticsearch.watcher.condition.ConditionException;
/**
*
*/
public class NeverConditionException extends ConditionException {
public NeverConditionException(String msg, Object... args) {
super(msg, args);
}
public NeverConditionException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -15,6 +15,8 @@ import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
import java.util.Map;
import static org.elasticsearch.watcher.support.Exceptions.invalidScript;
/**
* This class executes a script against the ctx payload and returns a boolean
*/
@ -29,7 +31,7 @@ public class ExecutableScriptCondition extends ExecutableCondition<ScriptConditi
try {
compiledScript = scriptService.compile(condition.script);
} catch (Exception e) {
throw new ScriptConditionValidationException("failed to compile script [{}] with lang [{}] of type [{}]", e, condition.script.script(), condition.script.lang(), condition.script.type(), e);
throw invalidScript("failed to compile script [{}] with lang [{}] of type [{}]", e, condition.script.script(), condition.script.lang(), condition.script.type(), e);
}
}
@ -53,6 +55,6 @@ public class ExecutableScriptCondition extends ExecutableCondition<ScriptConditi
if (value instanceof Boolean) {
return (Boolean) value ? ScriptCondition.Result.MET : ScriptCondition.Result.UNMET;
}
throw new ScriptConditionException("script [{}] must return a boolean value (true|false) but instead returned [{}]", type(), ctx.watch().id(), condition.script.script(), value);
throw invalidScript("condition [{}] must return a boolean value (true|false) but instead returned [{}]", type(), ctx.watch().id(), condition.script.script(), value);
}
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.condition.script;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.condition.Condition;
@ -58,8 +59,8 @@ public class ScriptCondition implements Condition {
try {
Script script = Script.parse(parser);
return new ScriptCondition(script);
} catch (Script.ParseException pe) {
throw new ScriptConditionException("could not parse [{}] condition for watch [{}]. failed to parse script", pe, TYPE, watchId);
} catch (ElasticsearchParseException pe) {
throw new ElasticsearchParseException("could not parse [{}] condition for watch [{}]. failed to parse script", pe, TYPE, watchId);
}
}

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.condition.script;
import org.elasticsearch.watcher.condition.ConditionException;
/**
*
*/
public class ScriptConditionException extends ConditionException {
public ScriptConditionException(String msg, Object... args) {
super(msg, args);
}
public ScriptConditionException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -1,19 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.condition.script;
/**
*/
public class ScriptConditionValidationException extends ScriptConditionException {
public ScriptConditionValidationException(String msg, Object... args) {
super(msg, args);
}
public ScriptConditionValidationException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -5,10 +5,10 @@
*/
package org.elasticsearch.watcher.execution;
import org.elasticsearch.watcher.WatcherException;
import java.util.Locale;
import static org.elasticsearch.watcher.support.Exceptions.illegalArgument;
/**
*
*/
@ -69,7 +69,7 @@ public enum ActionExecutionMode {
case 4: return FORCE_EXECUTE;
case 5: return SKIP;
}
throw new WatcherException("unknown action execution mode id [{}]", id);
throw illegalArgument("unknown action execution mode id [{}]", id);
}
public static ActionExecutionMode resolve(String key) {
@ -83,6 +83,6 @@ public enum ActionExecutionMode {
case "force_execute": return FORCE_EXECUTE;
case "skip": return SKIP;
}
throw new WatcherException("unknown action execution mode [{}]", key);
throw illegalArgument("unknown action execution mode [{}]", key);
}
}

View File

@ -5,7 +5,11 @@
*/
package org.elasticsearch.watcher.execution;
import com.google.common.collect.Iterables;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.watcher.trigger.TriggerEngine;
import org.elasticsearch.watcher.trigger.TriggerEvent;
import org.elasticsearch.watcher.trigger.TriggerService;
@ -14,17 +18,24 @@ import org.elasticsearch.watcher.trigger.TriggerService;
*/
public class AsyncTriggerListener implements TriggerEngine.Listener {
private final ESLogger logger;
private final ExecutionService executionService;
@Inject
public AsyncTriggerListener(ExecutionService executionService, TriggerService triggerService) {
public AsyncTriggerListener(Settings settings, ExecutionService executionService, TriggerService triggerService) {
this.logger = Loggers.getLogger(SyncTriggerListener.class, settings);
this.executionService = executionService;
triggerService.register(this);
}
@Override
public void triggered(Iterable<TriggerEvent> events) {
executionService.processEventsAsync(events);
try {
executionService.processEventsAsync(events);
} catch (Exception e) {
logger.error("failed to process triggered events [{}]", e, Iterables.toArray(events, TriggerEvent.class));
}
}
}

View File

@ -6,7 +6,6 @@
package org.elasticsearch.watcher.execution;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.watcher.support.WatcherInactiveException;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
@ -15,6 +14,8 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import static org.elasticsearch.watcher.support.Exceptions.illegalState;
public class CurrentExecutions implements Iterable<ExecutionService.WatchExecution> {
private final ConcurrentMap<String, ExecutionService.WatchExecution> currentExecutions = new ConcurrentHashMap<>();
@ -27,7 +28,7 @@ public class CurrentExecutions implements Iterable<ExecutionService.WatchExecuti
try {
if (seal) {
// We shouldn't get here, because, ExecutionService#started should have been set to false
throw new WatcherInactiveException("could not register execution [{}]. current executions are sealed and forbid registrations of additional executions.", id);
throw illegalState("could not register execution [{}]. current executions are sealed and forbid registrations of additional executions.", id);
}
currentExecutions.put(id, execution);
} finally {

View File

@ -13,13 +13,11 @@ import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.actions.ActionWrapper;
import org.elasticsearch.watcher.condition.Condition;
import org.elasticsearch.watcher.history.HistoryStore;
import org.elasticsearch.watcher.history.WatchRecord;
import org.elasticsearch.watcher.input.Input;
import org.elasticsearch.watcher.support.WatcherInactiveException;
import org.elasticsearch.watcher.support.clock.Clock;
import org.elasticsearch.watcher.support.validation.WatcherSettingsValidation;
import org.elasticsearch.watcher.transform.Transform;
@ -73,7 +71,7 @@ public class ExecutionService extends AbstractComponent {
}
}
public void start(ClusterState state) {
public void start(ClusterState state) throws Exception {
if (started.get()) {
return;
}
@ -166,7 +164,7 @@ public class ExecutionService extends AbstractComponent {
return queuedWatches;
}
void processEventsAsync(Iterable<TriggerEvent> events) throws WatcherException {
void processEventsAsync(Iterable<TriggerEvent> events) throws Exception {
if (!started.get()) {
throw new IllegalStateException("not started");
}
@ -191,7 +189,12 @@ public class ExecutionService extends AbstractComponent {
@Override
public void onResponse(List<Integer> successFullSlots) {
for (Integer slot : successFullSlots) {
executeAsync(contexts.get(slot), triggeredWatches.get(slot));
TriggeredWatch triggeredWatch = triggeredWatches.get(slot);
try {
executeAsync(contexts.get(slot), triggeredWatch);
} catch (Exception e) {
logger.error("failed to execute watch [{}]", e, triggeredWatch.id());
}
}
}
@ -207,7 +210,7 @@ public class ExecutionService extends AbstractComponent {
});
}
void processEventsSync(Iterable<TriggerEvent> events) throws WatcherException {
void processEventsSync(Iterable<TriggerEvent> events) throws Exception {
if (!started.get()) {
throw new IllegalStateException("not started");
}
@ -311,7 +314,7 @@ public class ExecutionService extends AbstractComponent {
triggered (it'll have its history record)
*/
private void executeAsync(WatchExecutionContext ctx, TriggeredWatch triggeredWatch) {
private void executeAsync(WatchExecutionContext ctx, TriggeredWatch triggeredWatch) throws Exception {
try {
executor.execute(new WatchExecutionTask(ctx));
} catch (EsRejectedExecutionException e) {
@ -371,7 +374,7 @@ public class ExecutionService extends AbstractComponent {
return ctx.finish();
}
void executeTriggeredWatches(Collection<TriggeredWatch> triggeredWatches) {
void executeTriggeredWatches(Collection<TriggeredWatch> triggeredWatches) throws Exception {
assert triggeredWatches != null;
int counter = 0;
for (TriggeredWatch triggeredWatch : triggeredWatches) {
@ -402,10 +405,6 @@ public class ExecutionService extends AbstractComponent {
public void run() {
try {
execute(ctx);
} catch (WatcherInactiveException e) {
// When can end up here when acquiring the lock or adding a watch to the current executions while shutting down.
// Once we a watch is added to the current executions we shouldn't end up here.
logger.debug("could not execute watch [{}]/[{}]. watcher is not active", e, ctx.watch().id(), ctx.id());
} catch (Exception e) {
logger.error("could not execute watch [{}]/[{}]", e, ctx.watch().id(), ctx.id());
}

View File

@ -5,8 +5,6 @@
*/
package org.elasticsearch.watcher.execution;
import org.elasticsearch.watcher.WatcherException;
import java.util.Locale;
public enum ExecutionState {
@ -22,11 +20,7 @@ public enum ExecutionState {
}
public static ExecutionState resolve(String id) {
try {
return valueOf(id.toUpperCase(Locale.ROOT));
} catch (IllegalArgumentException iae) {
throw new WatcherException("unknown execution state [{}]", id);
}
return valueOf(id.toUpperCase(Locale.ROOT));
}
@Override

View File

@ -5,7 +5,11 @@
*/
package org.elasticsearch.watcher.execution;
import com.google.common.collect.Iterables;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.watcher.trigger.TriggerEngine;
import org.elasticsearch.watcher.trigger.TriggerEvent;
import org.elasticsearch.watcher.trigger.TriggerService;
@ -15,16 +19,22 @@ import org.elasticsearch.watcher.trigger.TriggerService;
public class SyncTriggerListener implements TriggerEngine.Listener {
private final ExecutionService executionService;
private final ESLogger logger;
@Inject
public SyncTriggerListener(ExecutionService executionService, TriggerService triggerService) {
public SyncTriggerListener(Settings settings, ExecutionService executionService, TriggerService triggerService) {
this.logger = Loggers.getLogger(SyncTriggerListener.class, settings);
this.executionService = executionService;
triggerService.register(this);
}
@Override
public void triggered(Iterable<TriggerEvent> events) {
executionService.processEventsSync(events);
try {
executionService.processEventsSync(events);
} catch (Exception e) {
logger.error("failed to process triggered events [{}]", e, Iterables.toArray(events, TriggerEvent.class));
}
}
}

View File

@ -26,8 +26,6 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.watcher.history.HistoryException;
import org.elasticsearch.watcher.history.TriggeredWatchException;
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
import java.io.IOException;
@ -40,6 +38,9 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import static org.elasticsearch.watcher.support.Exceptions.illegalState;
import static org.elasticsearch.watcher.support.Exceptions.ioException;
public class TriggeredWatchStore extends AbstractComponent {
public static final String INDEX_NAME = ".triggered_watches";
@ -90,7 +91,7 @@ public class TriggeredWatchStore extends AbstractComponent {
}
}
public void put(TriggeredWatch triggeredWatch) throws HistoryException {
public void put(TriggeredWatch triggeredWatch) throws Exception {
ensureStarted();
accessLock.lock();
try {
@ -99,13 +100,13 @@ public class TriggeredWatchStore extends AbstractComponent {
.opType(IndexRequest.OpType.CREATE);
client.index(request, (TimeValue) null);
} catch (IOException e) {
throw new TriggeredWatchException("failed to persist triggered watch [{}]", e, triggeredWatch);
throw ioException("failed to persist triggered watch [{}]", e, triggeredWatch);
} finally {
accessLock.unlock();
}
}
public void put(final TriggeredWatch triggeredWatch, final ActionListener<Boolean> listener) throws TriggeredWatchException {
public void put(final TriggeredWatch triggeredWatch, final ActionListener<Boolean> listener) throws Exception {
ensureStarted();
try {
IndexRequest request = new IndexRequest(INDEX_NAME, DOC_TYPE, triggeredWatch.id().value())
@ -123,11 +124,11 @@ public class TriggeredWatchStore extends AbstractComponent {
}
});
} catch (IOException e) {
throw new TriggeredWatchException("failed to persist triggered watch [{}]", e, triggeredWatch);
throw ioException("failed to persist triggered watch [{}]", e, triggeredWatch);
}
}
public void putAll(final List<TriggeredWatch> triggeredWatches, final ActionListener<List<Integer>> listener) throws TriggeredWatchException {
public void putAll(final List<TriggeredWatch> triggeredWatches, final ActionListener<List<Integer>> listener) throws Exception {
if (triggeredWatches.isEmpty()) {
listener.onResponse(Collections.EMPTY_LIST);
@ -180,11 +181,11 @@ public class TriggeredWatchStore extends AbstractComponent {
}
});
} catch (IOException e) {
throw new TriggeredWatchException("failed to persist triggered watches", e);
throw ioException("failed to persist triggered watches", e);
}
}
public List<Integer> putAll(final List<TriggeredWatch> triggeredWatches) throws TriggeredWatchException {
public List<Integer> putAll(final List<TriggeredWatch> triggeredWatches) throws Exception {
ensureStarted();
try {
BulkRequest request = new BulkRequest();
@ -207,18 +208,18 @@ public class TriggeredWatchStore extends AbstractComponent {
}
return successFullSlots;
} catch (IOException e) {
throw new TriggeredWatchException("failed to persist triggered watches", e);
throw ioException("failed to persist triggered watches", e);
}
}
public void delete(Wid wid) throws TriggeredWatchException {
public void delete(Wid wid) throws Exception {
ensureStarted();
accessLock.lock();
try {
DeleteRequest request = new DeleteRequest(INDEX_NAME, DOC_TYPE, wid.value());
client.delete(request);
logger.trace("successfully deleted triggered watch with id [{}]", wid);
} finally {
} finally {
accessLock.unlock();
}
}
@ -232,13 +233,13 @@ public class TriggeredWatchStore extends AbstractComponent {
int numPrimaryShards;
if (!state.routingTable().index(INDEX_NAME).allPrimaryShardsActive()) {
throw new TriggeredWatchException("not all primary shards of the [{}] index are started.", INDEX_NAME);
throw illegalState("not all primary shards of the [{}] index are started.", INDEX_NAME);
} else {
numPrimaryShards = indexMetaData.numberOfShards();
}
RefreshResponse refreshResponse = client.refresh(new RefreshRequest(INDEX_NAME));
if (refreshResponse.getSuccessfulShards() < numPrimaryShards) {
throw new TriggeredWatchException("refresh was supposed to run on [{}] shards, but ran on [{}] shards", numPrimaryShards, refreshResponse.getSuccessfulShards());
throw illegalState("refresh was supposed to run on [{}] shards, but ran on [{}] shards", numPrimaryShards, refreshResponse.getSuccessfulShards());
}
SearchRequest searchRequest = createScanSearchRequest();
@ -246,7 +247,7 @@ public class TriggeredWatchStore extends AbstractComponent {
List<TriggeredWatch> triggeredWatches = new ArrayList<>();
try {
if (response.getTotalShards() != response.getSuccessfulShards()) {
throw new TriggeredWatchException("scan search was supposed to run on [{}] shards, but ran on [{}] shards", numPrimaryShards, response.getSuccessfulShards());
throw illegalState("scan search was supposed to run on [{}] shards, but ran on [{}] shards", numPrimaryShards, response.getSuccessfulShards());
}
if (response.getHits().getTotalHits() > 0) {
@ -286,7 +287,7 @@ public class TriggeredWatchStore extends AbstractComponent {
private void ensureStarted() {
if (!started.get()) {
throw new TriggeredWatchException("unable to persist triggered watches, the store is not ready");
throw illegalState("unable to persist triggered watches, the store is not ready");
}
}

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.execution;
import org.elasticsearch.watcher.WatcherException;
/**
*
*/
public class WatchExecutionException extends WatcherException {
public WatchExecutionException(String msg, Object... args) {
super(msg, args);
}
public WatchExecutionException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -5,11 +5,12 @@
*/
package org.elasticsearch.watcher.execution;
import org.elasticsearch.watcher.WatcherException;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import static org.elasticsearch.watcher.support.Exceptions.illegalArgument;
/**
*
*/
@ -30,7 +31,7 @@ public class Wid {
this.value = value;
int index = value.lastIndexOf("_");
if (index <= 0) {
throw new WatcherException("invalid watcher execution id [{}]", value);
throw illegalArgument("invalid watcher execution id [{}]", value);
}
this.watchId = value.substring(0, index);
}

View File

@ -1,21 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.history;
import org.elasticsearch.watcher.WatcherException;
/**
*/
public class HistoryException extends WatcherException {
public HistoryException(String msg, Object... args) {
super(msg, args);
}
public HistoryException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@ -26,6 +26,8 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import static org.elasticsearch.watcher.support.Exceptions.ioException;
/**
*/
public class HistoryStore extends AbstractComponent {
@ -83,9 +85,9 @@ public class HistoryStore extends AbstractComponent {
}
public void put(WatchRecord watchRecord) throws HistoryException {
public void put(WatchRecord watchRecord) throws Exception {
if (!started.get()) {
throw new HistoryException("unable to persist watch record history store is not ready");
throw new IllegalStateException("unable to persist watch record history store is not ready");
}
String index = getHistoryIndexNameForTime(watchRecord.triggerEvent().triggeredTime());
putUpdateLock.lock();
@ -94,8 +96,8 @@ public class HistoryStore extends AbstractComponent {
.source(XContentFactory.jsonBuilder().value(watchRecord))
.opType(IndexRequest.OpType.CREATE);
client.index(request, (TimeValue) null);
} catch (IOException e) {
throw new HistoryException("failed to persist watch record [" + watchRecord + "]", e);
} catch (IOException ioe) {
throw ioException("failed to persist watch record [{}]", ioe, watchRecord);
} finally {
putUpdateLock.unlock();
}

View File

@ -1,20 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.history;
import org.elasticsearch.watcher.WatcherException;
public class TriggeredWatchException extends WatcherException {
public TriggeredWatchException(String msg, Object... args) {
super(msg, args);
}
public TriggeredWatchException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.input;
import org.elasticsearch.watcher.WatcherException;
/**
*
*/
public class InputException extends WatcherException {
public InputException(String msg, Object... args) {
super(msg, args);
}
public InputException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -6,6 +6,7 @@
package org.elasticsearch.watcher.input;
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.xcontent.XContentParser;
@ -35,7 +36,7 @@ public class InputRegistry {
String type = null;
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
throw new InputException("could not parse input for watch [{}]. expected an object representing the input, but found [{}] instead", watchId, parser.currentToken());
throw new ElasticsearchParseException("could not parse input for watch [{}]. expected an object representing the input, but found [{}] instead", watchId, parser.currentToken());
}
XContentParser.Token token;
@ -44,20 +45,20 @@ public class InputRegistry {
if (token == XContentParser.Token.FIELD_NAME) {
type = parser.currentName();
} else if (type == null) {
throw new InputException("could not parse input for watch [{}]. expected field indicating the input type, but found [{}] instead", watchId, token);
throw new ElasticsearchParseException("could not parse input for watch [{}]. expected field indicating the input type, but found [{}] instead", watchId, token);
} else if (token == XContentParser.Token.START_OBJECT) {
InputFactory factory = factories.get(type);
if (factory == null) {
throw new InputException("could not parse input for watch [{}]. unknown input type [{}]", watchId, type);
throw new ElasticsearchParseException("could not parse input for watch [{}]. unknown input type [{}]", watchId, type);
}
input = factory.parseExecutable(watchId, parser);
} else {
throw new InputException("could not parse input for watch [{}]. expected an object representing input [{}], but found [{}] instead", watchId, type, token);
throw new ElasticsearchParseException("could not parse input for watch [{}]. expected an object representing input [{}], but found [{}] instead", watchId, type, token);
}
}
if (input == null) {
throw new InputException("could not parse input for watch [{}]. expected field indicating the input type, but found an empty object instead", watchId, token);
throw new ElasticsearchParseException("could not parse input for watch [{}]. expected field indicating the input type, but found an empty object instead", watchId, token);
}
return input;

View File

@ -6,6 +6,7 @@
package org.elasticsearch.watcher.input.http;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
@ -74,7 +75,7 @@ public class ExecutableHttpInput extends ExecutableInput<HttpInput, HttpInput.Re
try {
parser = contentType.xContent().createParser(response.body());
} catch (Exception e) {
throw new HttpInputException("could not parse response body [{}] it does not appear to be [{}]", type(), ctx.id(), response.body().toUtf8(), contentType.shortName());
throw new ElasticsearchParseException("could not parse response body [{}] it does not appear to be [{}]", type(), ctx.id(), response.body().toUtf8(), contentType.shortName());
}
}

View File

@ -6,6 +6,7 @@
package org.elasticsearch.watcher.input.http;
import com.google.common.collect.ImmutableSet;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
@ -83,8 +84,8 @@ public class HttpInput implements Input {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.REQUEST)) {
try {
request = requestParser.parse(parser);
} catch (HttpRequestTemplate.ParseException pe) {
throw new HttpInputException("could not parse [{}] input for watch [{}]. failed to parse http request template", pe, TYPE, watchId);
} catch (ElasticsearchParseException pe) {
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. failed to parse http request template", pe, TYPE, watchId);
}
} else if (token == XContentParser.Token.START_ARRAY) {
if (Field.EXTRACT.getPreferredName().equals(currentFieldName)) {
@ -93,32 +94,32 @@ public class HttpInput implements Input {
if (token == XContentParser.Token.VALUE_STRING) {
extract.add(parser.text());
} else {
throw new HttpInputException("could not parse [{}] input for watch [{}]. expected a string value as an [{}] item but found [{}] instead", TYPE, watchId, currentFieldName, token);
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. expected a string value as an [{}] item but found [{}] instead", TYPE, watchId, currentFieldName, token);
}
}
} else {
throw new HttpInputException("could not parse [{}] input for watch [{}]. unexpected array field [{}]", TYPE, watchId, currentFieldName);
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. unexpected array field [{}]", TYPE, watchId, currentFieldName);
}
} else if (token == XContentParser.Token.VALUE_STRING) {
if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.RESPONSE_CONTENT_TYPE)) {
expectedResponseBodyType = HttpContentType.resolve(parser.text());
if (expectedResponseBodyType == null) {
throw new HttpInputException("could not parse [{}] input for watch [{}]. unknown content type [{}]", TYPE, watchId, parser.text());
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. unknown content type [{}]", TYPE, watchId, parser.text());
}
} else {
throw new HttpInputException("could not parse [{}] input for watch [{}]. unexpected string field [{}]", TYPE, watchId, currentFieldName);
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. unexpected string field [{}]", TYPE, watchId, currentFieldName);
}
} else {
throw new HttpInputException("could not parse [{}] input for watch [{}]. unexpected token [{}]", TYPE, watchId, token);
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. unexpected token [{}]", TYPE, watchId, token);
}
}
if (request == null) {
throw new HttpInputException("could not parse [{}] input for watch [{}]. missing require [{}] field", TYPE, watchId, Field.REQUEST.getPreferredName());
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. missing require [{}] field", TYPE, watchId, Field.REQUEST.getPreferredName());
}
if (expectedResponseBodyType == HttpContentType.TEXT && extract != null ) {
throw new HttpInputException("could not parse [{}] input for watch [{}]. key extraction is not supported for content type [{}]", TYPE, watchId, expectedResponseBodyType);
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. key extraction is not supported for content type [{}]", TYPE, watchId, expectedResponseBodyType);
}
return new HttpInput(request, expectedResponseBodyType, extract);

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.input.http;
import org.elasticsearch.watcher.input.InputException;
/**
*
*/
public class HttpInputException extends InputException {
public HttpInputException(String msg, Object... args) {
super(msg, args);
}
public HttpInputException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.input.none;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.input.Input;
@ -35,10 +36,10 @@ public class NoneInput implements Input {
public static NoneInput parse(String watchId, XContentParser parser) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
throw new NoneInputException("could not parse [{}] input for watch [{}]. expected an empty object but found [{}] instead", TYPE, watchId, parser.currentToken());
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. expected an empty object but found [{}] instead", TYPE, watchId, parser.currentToken());
}
if (parser.nextToken() != XContentParser.Token.END_OBJECT) {
throw new NoneInputException("could not parse [{}] input for watch [{}]. expected an empty object but found [{}] instead", TYPE, watchId, parser.currentToken());
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. expected an empty object but found [{}] instead", TYPE, watchId, parser.currentToken());
}
return INSTANCE;
}

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.input.none;
import org.elasticsearch.watcher.input.InputException;
/**
*
*/
public class NoneInputException extends InputException {
public NoneInputException(String msg, Object... args) {
super(msg, args);
}
public NoneInputException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -6,6 +6,7 @@
package org.elasticsearch.watcher.input.search;
import com.google.common.collect.ImmutableSet;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
@ -15,7 +16,6 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.input.Input;
import org.elasticsearch.watcher.support.SearchRequestEquivalence;
import org.elasticsearch.watcher.support.SearchRequestParseException;
import org.elasticsearch.watcher.support.WatcherDateTimeUtils;
import org.elasticsearch.watcher.support.WatcherUtils;
import org.elasticsearch.watcher.watch.Payload;
@ -121,8 +121,8 @@ public class SearchInput implements Input {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.REQUEST)) {
try {
request = WatcherUtils.readSearchRequest(parser, ExecutableSearchInput.DEFAULT_SEARCH_TYPE);
} catch (SearchRequestParseException srpe) {
throw new SearchInputException("could not parse [{}] input for watch [{}]. failed to parse [{}]", srpe, TYPE, watchId, currentFieldName);
} catch (ElasticsearchParseException srpe) {
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. failed to parse [{}]", srpe, TYPE, watchId, currentFieldName);
}
} else if (token == XContentParser.Token.START_ARRAY) {
if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.EXTRACT)) {
@ -131,11 +131,11 @@ public class SearchInput implements Input {
if (token == XContentParser.Token.VALUE_STRING) {
extract.add(parser.text());
} else {
throw new SearchInputException("could not parse [{}] input for watch [{}]. expected a string value in [{}] array, but found [{}] instead", TYPE, watchId, currentFieldName, token);
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. expected a string value in [{}] array, but found [{}] instead", TYPE, watchId, currentFieldName, token);
}
}
} else {
throw new SearchInputException("could not parse [{}] input for watch [{}]. unexpected array field [{}]", TYPE, watchId, currentFieldName);
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. unexpected array field [{}]", TYPE, watchId, currentFieldName);
}
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.TIMEOUT)) {
timeout = WatcherDateTimeUtils.parseTimeValue(parser, Field.TIMEOUT.toString());
@ -143,15 +143,15 @@ public class SearchInput implements Input {
if (token == XContentParser.Token.VALUE_STRING) {
dynamicNameTimeZone = DateTimeZone.forID(parser.text());
} else {
throw new SearchInputException("could not parse [{}] input for watch [{}]. failed to parse [{}]. must be a string value (e.g. 'UTC' or '+01:00').", TYPE, watchId, currentFieldName);
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. failed to parse [{}]. must be a string value (e.g. 'UTC' or '+01:00').", TYPE, watchId, currentFieldName);
}
} else {
throw new SearchInputException("could not parse [{}] input for watch [{}]. unexpected token [{}]", TYPE, watchId, token);
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. unexpected token [{}]", TYPE, watchId, token);
}
}
if (request == null) {
throw new SearchInputException("could not parse [{}] input for watch [{}]. missing required [{}] field", TYPE, watchId, Field.REQUEST.getPreferredName());
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. missing required [{}] field", TYPE, watchId, Field.REQUEST.getPreferredName());
}
return new SearchInput(request, extract, timeout, dynamicNameTimeZone);
}

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.input.search;
import org.elasticsearch.watcher.input.InputException;
/**
*
*/
public class SearchInputException extends InputException {
public SearchInputException(String msg, Object... args) {
super(msg, args);
}
public SearchInputException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.input.simple;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.input.Input;
@ -56,7 +57,7 @@ public class SimpleInput implements Input {
public static SimpleInput parse(String watchId, XContentParser parser) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
throw new SimpleInputException("could not parse [{}] input for watch [{}]. expected an object but found [{}] instead", TYPE, watchId, parser.currentToken());
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. expected an object but found [{}] instead", TYPE, watchId, parser.currentToken());
}
Payload payload = new Payload.Simple(parser.map());
return new SimpleInput(payload);

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.input.simple;
import org.elasticsearch.watcher.input.InputException;
/**
*
*/
public class SimpleInputException extends InputException {
public SimpleInputException(String msg, Object... args) {
super(msg, args);
}
public SimpleInputException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -28,8 +28,8 @@ public class LicenseService extends AbstractLifecycleComponent<LicenseService> {
public static final String FEATURE_NAME = WatcherPlugin.NAME;
private static final LicensesService.TrialLicenseOptions TRIAL_LICENSE_OPTIONS =
new LicensesService.TrialLicenseOptions(TimeValue.timeValueHours(30 * 24), 1000);
private static final LicensesClientService.TrialLicenseOptions TRIAL_LICENSE_OPTIONS =
new LicensesClientService.TrialLicenseOptions(TimeValue.timeValueHours(30 * 24), 1000);
private static final FormatDateTimeFormatter DATE_FORMATTER = Joda.forPattern("EEEE, MMMMM dd, yyyy", Locale.ROOT);

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.rest.action;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
@ -15,7 +16,6 @@ import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.rest.*;
import org.elasticsearch.rest.action.support.RestBuilderListener;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.client.WatcherClient;
import org.elasticsearch.watcher.execution.ActionExecutionMode;
import org.elasticsearch.watcher.rest.WatcherRestHandler;
@ -86,7 +86,7 @@ public class RestExecuteWatchAction extends WatcherRestHandler {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.RECORD_EXECUTION)) {
builder.setRecordExecution(parser.booleanValue());
} else {
throw new ParseException("could not parse watch execution request. unexpected boolean field [{}]", currentFieldName);
throw new ElasticsearchParseException("could not parse watch execution request. unexpected boolean field [{}]", currentFieldName);
}
} else if (token == XContentParser.Token.START_OBJECT) {
if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.ALTERNATIVE_INPUT)) {
@ -105,35 +105,24 @@ public class RestExecuteWatchAction extends WatcherRestHandler {
try {
ActionExecutionMode mode = ActionExecutionMode.resolve(parser.textOrNull());
builder.setActionMode(currentFieldName, mode);
} catch (WatcherException we) {
throw new ParseException("could not parse watch execution request", we);
} catch (IllegalArgumentException iae) {
throw new ElasticsearchParseException("could not parse watch execution request", iae);
}
} else {
throw new ParseException("could not parse watch execution request. unexpected array field [{}]", currentFieldName);
throw new ElasticsearchParseException("could not parse watch execution request. unexpected array field [{}]", currentFieldName);
}
}
} else {
throw new ParseException("could not parse watch execution request. unexpected object field [{}]", currentFieldName);
throw new ElasticsearchParseException("could not parse watch execution request. unexpected object field [{}]", currentFieldName);
}
} else {
throw new ParseException("could not parse watch execution request. unexpected token [{}]", token);
throw new ElasticsearchParseException("could not parse watch execution request. unexpected token [{}]", token);
}
}
return builder.request();
}
public static class ParseException extends WatcherException {
public ParseException(String msg, Object... args) {
super(msg, args);
}
public ParseException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}
interface Field {
ParseField ID = new ParseField("_id");
ParseField WATCH_RECORD = new ParseField("watch_record");

View File

@ -5,13 +5,13 @@
*/
package org.elasticsearch.watcher.support;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.watcher.WatcherException;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
@ -141,10 +141,10 @@ public class DynamicIndexName implements ToXContent {
format = defaultFormat;
} else {
if (expression.lastIndexOf(RIGHT_BOUND) != expression.length() - 1) {
throw new ParseException("invalid dynamic name expression [{}]. missing closing `}` for date math format", expression);
throw new ElasticsearchParseException("invalid dynamic name expression [{}]. missing closing `}` for date math format", expression);
}
if (i == expression.length() - 2) {
throw new ParseException("invalid dynamic name expression [{}]. missing date format", expression);
throw new ElasticsearchParseException("invalid dynamic name expression [{}]. missing date format", expression);
}
mathExpression = expression.substring(0, i);
format = expression.substring(i + 1, expression.length() - 1);
@ -218,7 +218,7 @@ public class DynamicIndexName implements ToXContent {
inDateFormat = true;
sb.append(c);
} else {
throw new ParseException("invalid dynamic name expression [{}]. invalid character in placeholder at position [{}]", new String(text, from, length), i);
throw new ElasticsearchParseException("invalid dynamic name expression [{}]. invalid character in placeholder at position [{}]", new String(text, from, length), i);
}
break;
@ -254,7 +254,7 @@ public class DynamicIndexName implements ToXContent {
case RIGHT_BOUND:
if (!escapedChar) {
throw new ParseException("invalid dynamic name expression [{}]. invalid character at position [{}]. " +
throw new ElasticsearchParseException("invalid dynamic name expression [{}]. invalid character at position [{}]. " +
"`{` and `}` are reserved characters and should be escaped when used as part of the index name using `\\` (e.g. `\\{text\\}`)", new String(text, from, length), i);
}
default:
@ -263,7 +263,7 @@ public class DynamicIndexName implements ToXContent {
}
}
if (inPlaceHolder) {
throw new ParseException("invalid dynamic name expression [{}]. date math placeholder is open ended", new String(text, from, length));
throw new ElasticsearchParseException("invalid dynamic name expression [{}]. date math placeholder is open ended", new String(text, from, length));
}
if (sb.length() > 0) {
expressions.add(new StaticExpression(sb.toString()));
@ -333,17 +333,5 @@ public class DynamicIndexName implements ToXContent {
}
return dynamicIndexNames;
}
}
public static class ParseException extends WatcherException {
public ParseException(String msg, Object... args) {
super(msg, args);
}
public ParseException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}
}

View File

@ -0,0 +1,58 @@
/*
* 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.support;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.script.ScriptException;
import java.io.IOException;
import java.util.IllegalFormatException;
import static org.elasticsearch.common.logging.support.LoggerMessageFormat.format;
/**
*
*/
public class Exceptions {
private Exceptions() {
}
public static IllegalArgumentException illegalArgument(String msg, Object... args) {
return new IllegalArgumentException(format(msg, args));
}
public static IllegalArgumentException illegalArgument(String msg, Throwable cause, Object... args) {
return new IllegalArgumentException(format(msg, args), cause);
}
public static IllegalStateException illegalState(String msg, Object... args) {
return new IllegalStateException(format(msg, args));
}
public static IllegalStateException illegalState(String msg, Throwable cause, Object... args) {
return new IllegalStateException(format(msg, args), cause);
}
public static IOException ioException(String msg, Object... args) {
return new IOException(format(msg, args));
}
public static IOException ioException(String msg, Throwable cause, Object... args) {
return new IOException(format(msg, args), cause);
}
//todo remove once ScriptException supports varargs
public static ScriptException invalidScript(String msg, Object... args) {
throw new ScriptException(format(msg, args));
}
//todo remove once SettingsException supports varargs
public static SettingsException invalidSettings(String msg, Object... args) {
throw new SettingsException(format(msg, args));
}
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.support;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
@ -13,7 +14,6 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.ScriptService.ScriptType;
import org.elasticsearch.watcher.WatcherException;
import java.io.IOException;
import java.util.Collections;
@ -94,11 +94,9 @@ public class Script implements ToXContent {
case FILE:
builder.field(Field.FILE.getPreferredName(), script);
break;
case INDEXED:
builder.field(Field.ID.getPreferredName(), script);
break;
default:
throw new WatcherException("unsupported script type [{}]", type());
assert type == ScriptType.INDEXED : "script type [" + type + "] is not supported";
builder.field(Field.ID.getPreferredName(), script);
}
if (lang != null) {
builder.field(Field.LANG.getPreferredName(), lang);
@ -115,7 +113,7 @@ public class Script implements ToXContent {
return new Script(parser.text());
}
if (token != XContentParser.Token.START_OBJECT) {
throw new ParseException("expected a string value or an object, but found [{}] instead", token);
throw new ElasticsearchParseException("expected a string value or an object, but found [{}] instead", token);
}
String script = null;
@ -132,40 +130,40 @@ public class Script implements ToXContent {
if (token == XContentParser.Token.VALUE_STRING) {
script = parser.text();
} else {
throw new ParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token);
throw new ElasticsearchParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token);
}
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.FILE)) {
type = ScriptType.FILE;
if (token == XContentParser.Token.VALUE_STRING) {
script = parser.text();
} else {
throw new ParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token);
throw new ElasticsearchParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token);
}
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.ID)) {
type = ScriptType.INDEXED;
if (token == XContentParser.Token.VALUE_STRING) {
script = parser.text();
} else {
throw new ParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token);
throw new ElasticsearchParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token);
}
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.LANG)) {
if (token == XContentParser.Token.VALUE_STRING) {
lang = parser.text();
} else {
throw new ParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token);
throw new ElasticsearchParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token);
}
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.PARAMS)) {
if (token == XContentParser.Token.START_OBJECT) {
params = parser.map();
} else {
throw new ParseException("expected an object for field [{}], but found [{}]", currentFieldName, token);
throw new ElasticsearchParseException("expected an object for field [{}], but found [{}]", currentFieldName, token);
}
} else {
throw new ParseException("unexpected field [{}]", currentFieldName);
throw new ElasticsearchParseException("unexpected field [{}]", currentFieldName);
}
}
if (script == null) {
throw new ParseException("expected one of [{}], [{}] or [{}] fields, but found none", Field.INLINE.getPreferredName(), Field.FILE.getPreferredName(), Field.ID.getPreferredName());
throw new ElasticsearchParseException("expected one of [{}], [{}] or [{}] fields, but found none", Field.INLINE.getPreferredName(), Field.FILE.getPreferredName(), Field.ID.getPreferredName());
}
assert type != null : "if script is not null, type should definitely not be null";
return new Script(script, type, lang, params);
@ -260,17 +258,6 @@ public class Script implements ToXContent {
}
}
public static class ParseException extends WatcherException {
public ParseException(String msg, Object... args) {
super(msg, args);
}
public ParseException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}
interface Field {
ParseField INLINE = new ParseField("inline");
ParseField FILE = new ParseField("file");

View File

@ -7,12 +7,13 @@ package org.elasticsearch.watcher.support;
import com.google.common.base.Equivalence;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import java.io.IOException;
import java.util.Arrays;
import static org.elasticsearch.watcher.support.Exceptions.illegalState;
/**
* The only true way today to compare search request object (outside of core) is to
@ -38,7 +39,7 @@ public final class SearchRequestEquivalence extends Equivalence<SearchRequest> {
byte[] bytes2 = output1.bytes().toBytes();
return Arrays.equals(bytes1, bytes2);
} catch (Throwable t) {
throw new WatcherException("could not compare search requests", t);
throw illegalState("could not compare search requests", t);
}
}
@ -49,7 +50,7 @@ public final class SearchRequestEquivalence extends Equivalence<SearchRequest> {
request.writeTo(output);
return Arrays.hashCode(output.bytes().toBytes());
} catch (IOException ioe) {
throw new WatcherException("could not compute hashcode for search request", ioe);
throw illegalState("could not compute hashcode for search request", ioe);
}
}
}

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.support;
import org.elasticsearch.watcher.WatcherException;
/**
*
*/
public class SearchRequestParseException extends WatcherException {
public SearchRequestParseException(String msg) {
super(msg);
}
public SearchRequestParseException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@ -14,14 +14,12 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.core.DateFieldMapper;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.support.clock.Clock;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
/**
*
*/
@ -61,7 +59,7 @@ public class WatcherDateTimeUtils {
public static DateTime parseDateMath(String fieldName, XContentParser parser, DateTimeZone timeZone, Clock clock) throws IOException {
if (parser.currentToken() == XContentParser.Token.VALUE_NULL) {
throw new ParseException("could not parse date/time expected date field [{}] to not be null but was null", fieldName);
throw new ElasticsearchParseException("could not parse date/time expected date field [{}] to not be null but was null", fieldName);
}
return parseDateMathOrNull(fieldName, parser, timeZone, clock);
}
@ -75,13 +73,13 @@ public class WatcherDateTimeUtils {
try {
return parseDateMath(parser.text(), timeZone, clock);
} catch (ElasticsearchParseException epe) {
throw new ParseException("could not parse date/time. expected date field [{}] to be either a number or a DateMath string but found [{}] instead", epe, fieldName, parser.text());
throw new ElasticsearchParseException("could not parse date/time. expected date field [{}] to be either a number or a DateMath string but found [{}] instead", epe, fieldName, parser.text());
}
}
if (token == XContentParser.Token.VALUE_NULL) {
return null;
}
throw new ParseException("could not parse date/time. expected date field [{}] to be either a number or a string but found [{}] instead", fieldName, token);
throw new ElasticsearchParseException("could not parse date/time. expected date field [{}] to be either a number or a string but found [{}] instead", fieldName, token);
}
public static DateTime parseDateMath(String valueString, DateTimeZone timeZone, final Clock clock) {
@ -99,7 +97,7 @@ public class WatcherDateTimeUtils {
if (token == XContentParser.Token.VALUE_NULL) {
return null;
}
throw new ParseException("could not parse date/time. expected date field [{}] to be either a number or a string but found [{}] instead", fieldName, token);
throw new ElasticsearchParseException("could not parse date/time. expected date field [{}] to be either a number or a string but found [{}] instead", fieldName, token);
}
public static XContentBuilder writeDate(String fieldName, XContentBuilder builder, DateTime date) throws IOException {
@ -131,25 +129,15 @@ public class WatcherDateTimeUtils {
try {
TimeValue value = TimeValue.parseTimeValue(parser.text(), null, settingName);
if (value.millis() < 0) {
throw new ParseException("could not parse time value [{}]. Time value cannot be negative.", parser.text());
throw new ElasticsearchParseException("could not parse time value [{}]. Time value cannot be negative.", parser.text());
}
return value;
} catch (ElasticsearchParseException ex) {
throw new ParseException("failed to parse time unit", ex);
} catch (ElasticsearchParseException epe) {
throw new ElasticsearchParseException("failed to parse time unit", epe);
}
}
throw new ParseException("could not parse time value. expected either a string or a null value but found [{}] instead", token);
}
public static class ParseException extends WatcherException {
public ParseException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
public ParseException(String msg, Object... args) {
super(msg, args);
}
throw new ElasticsearchParseException("could not parse time value. expected either a string or a null value but found [{}] instead", token);
}
private static class ClockNowCallable implements Callable<Long> {

View File

@ -1,19 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.support;
import org.elasticsearch.watcher.WatcherException;
public class WatcherInactiveException extends WatcherException {
public WatcherInactiveException(String msg, Object... args) {
super(msg, args);
}
public WatcherInactiveException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.support;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.support.IndicesOptions;
@ -14,13 +15,12 @@ import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.joda.time.DateTime;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.*;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
import org.elasticsearch.watcher.support.template.Template;
import org.elasticsearch.watcher.watch.Payload;
import org.joda.time.DateTime;
import java.io.IOException;
import java.lang.reflect.Array;
@ -48,13 +48,9 @@ public final class WatcherUtils {
private WatcherUtils() {
}
public static Map<String, Object> responseToData(ToXContent response) {
try {
XContentBuilder builder = jsonBuilder().startObject().value(response).endObject();
return XContentHelper.convertToMap(builder.bytes(), false).v2();
} catch (IOException ioe) {
throw new WatcherException("failed to convert search response to script parameters", ioe);
}
public static Map<String, Object> responseToData(ToXContent response) throws IOException {
XContentBuilder builder = jsonBuilder().startObject().value(response).endObject();
return XContentHelper.convertToMap(builder.bytes(), false).v2();
}
public static SearchRequest createSearchRequestFromPrototype(SearchRequest requestPrototype, @Nullable DynamicIndexName[] dynamicIndexNames, WatchExecutionContext ctx, Payload payload) throws IOException {
@ -127,7 +123,7 @@ public final class WatcherUtils {
} else if (requestPrototype.templateName() != null) {
// In Watcher templates on all places can be defined in one format
// Can only be set via the Java api
throw new WatcherException("SearchRequest#templateName() isn't supported, templates should be defined in the request body");
throw Exceptions.illegalArgument("SearchRequest's templateName isn't supported, templates should be defined in the request body");
}
// falling back to an empty body
return request;
@ -155,7 +151,7 @@ public final class WatcherUtils {
if (token == XContentParser.Token.VALUE_STRING) {
indices.add(parser.textOrNull());
} else {
throw new SearchRequestParseException("could not read search request. expected string values in [" + currentFieldName + "] field, but instead found [" + token + "]");
throw new ElasticsearchParseException("could not read search request. expected string values in [" + currentFieldName + "] field, but instead found [" + token + "]");
}
}
searchRequest.indices(indices.toArray(new String[indices.size()]));
@ -165,12 +161,12 @@ public final class WatcherUtils {
if (token == XContentParser.Token.VALUE_STRING) {
types.add(parser.textOrNull());
} else {
throw new SearchRequestParseException("could not read search request. expected string values in [" + currentFieldName + "] field, but instead found [" + token + "]");
throw new ElasticsearchParseException("could not read search request. expected string values in [" + currentFieldName + "] field, but instead found [" + token + "]");
}
}
searchRequest.types(types.toArray(new String[types.size()]));
} else {
throw new SearchRequestParseException("could not read search request. unexpected array field [" + currentFieldName + "]");
throw new ElasticsearchParseException("could not read search request. unexpected array field [" + currentFieldName + "]");
}
} else if (token == XContentParser.Token.START_OBJECT) {
if (ParseFieldMatcher.STRICT.match(currentFieldName, BODY_FIELD)) {
@ -205,17 +201,17 @@ public final class WatcherUtils {
expandClosed = false;
break;
default:
throw new SearchRequestParseException("could not read search request. unknown value [" + parser.text() + "] for [" + currentFieldName + "] field ");
throw new ElasticsearchParseException("could not read search request. unknown value [" + parser.text() + "] for [" + currentFieldName + "] field ");
}
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, IGNORE_UNAVAILABLE_FIELD)) {
ignoreUnavailable = parser.booleanValue();
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, ALLOW_NO_INDICES_FIELD)) {
allowNoIndices = parser.booleanValue();
} else {
throw new SearchRequestParseException("could not read search request. unexpected index option [" + currentFieldName + "]");
throw new ElasticsearchParseException("could not read search request. unexpected index option [" + currentFieldName + "]");
}
} else {
throw new SearchRequestParseException("could not read search request. unexpected object field [" + currentFieldName + "]");
throw new ElasticsearchParseException("could not read search request. unexpected object field [" + currentFieldName + "]");
}
}
indicesOptions = IndicesOptions.fromOptions(ignoreUnavailable, allowNoIndices, expandOpen, expandClosed, DEFAULT_INDICES_OPTIONS);
@ -224,7 +220,7 @@ public final class WatcherUtils {
builder.copyCurrentStructure(parser);
templateBody = builder.string();
} else {
throw new SearchRequestParseException("could not read search request. unexpected object field [" + currentFieldName + "]");
throw new ElasticsearchParseException("could not read search request. unexpected object field [" + currentFieldName + "]");
}
} else if (token == XContentParser.Token.VALUE_STRING) {
if (ParseFieldMatcher.STRICT.match(currentFieldName, INDICES_FIELD)) {
@ -236,13 +232,13 @@ public final class WatcherUtils {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, SEARCH_TYPE_FIELD)) {
searchType = SearchType.fromString(parser.text().toLowerCase(Locale.ROOT), ParseFieldMatcher.STRICT);
if (searchType == SearchType.SCAN){
throw new SearchRequestParseException("could not read search request. value [" + searchType.name() + "] is not supported for field [" + SEARCH_TYPE_FIELD.getPreferredName() + "]" );
throw new ElasticsearchParseException("could not read search request. value [" + searchType.name() + "] is not supported for field [" + SEARCH_TYPE_FIELD.getPreferredName() + "]" );
}
} else {
throw new SearchRequestParseException("could not read search request. unexpected string field [" + currentFieldName + "]");
throw new ElasticsearchParseException("could not read search request. unexpected string field [" + currentFieldName + "]");
}
} else {
throw new SearchRequestParseException("could not read search request. unexpected token [" + token + "]");
throw new ElasticsearchParseException("could not read search request. unexpected token [" + token + "]");
}
}

View File

@ -6,7 +6,6 @@
package org.elasticsearch.watcher.support;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.WatcherException;
import java.io.IOException;
import java.util.*;
@ -18,7 +17,7 @@ public final class XContentFilterKeysUtils {
private XContentFilterKeysUtils() {
}
public static Map<String, Object> filterMapOrdered(Set<String> keys, XContentParser parser) {
public static Map<String, Object> filterMapOrdered(Set<String> keys, XContentParser parser) throws IOException {
try {
if (parser.currentToken() != null) {
throw new IllegalArgumentException("Parser already started");
@ -29,7 +28,7 @@ public final class XContentFilterKeysUtils {
State state = new State(new ArrayList<>(keys));
return parse(parser, state);
} catch (IOException e) {
throw new WatcherException("could not build a filtered payload out of xcontent", e);
throw new IOException("could not build a filtered payload out of xcontent", e);
}
}

View File

@ -8,11 +8,12 @@ package org.elasticsearch.watcher.support.http;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.watcher.WatcherException;
import java.io.IOException;
import java.util.Locale;
import static org.elasticsearch.watcher.support.Exceptions.illegalArgument;
/**
*/
public enum HttpContentType implements ToXContent {
@ -60,7 +61,7 @@ public enum HttpContentType implements ToXContent {
case "yaml": return YAML;
case "text": return TEXT;
default:
throw new WatcherException("unknown content type [{}]", id);
throw illegalArgument("unknown http content type [{}]", id);
}
}
}

View File

@ -6,6 +6,7 @@
package org.elasticsearch.watcher.support.http;
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
@ -14,7 +15,6 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.support.WatcherDateTimeUtils;
import org.elasticsearch.watcher.support.WatcherUtils;
import org.elasticsearch.watcher.support.http.auth.HttpAuth;
@ -208,14 +208,14 @@ public class HttpRequest implements ToXContent {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.CONNECTION_TIMEOUT)) {
try {
builder.connectionTimeout(WatcherDateTimeUtils.parseTimeValue(parser, Field.CONNECTION_TIMEOUT.toString()));
} catch (WatcherDateTimeUtils.ParseException pe) {
throw new ParseException("could not parse http request. invalid time value for [{}] field", pe, currentFieldName);
} catch (ElasticsearchParseException pe) {
throw new ElasticsearchParseException("could not parse http request. invalid time value for [{}] field", pe, currentFieldName);
}
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.READ_TIMEOUT)) {
try {
builder.readTimeout(WatcherDateTimeUtils.parseTimeValue(parser, Field.READ_TIMEOUT.toString()));
} catch (WatcherDateTimeUtils.ParseException pe) {
throw new ParseException("could not parse http request. invalid time value for [{}] field", pe, currentFieldName);
} catch (ElasticsearchParseException pe) {
throw new ElasticsearchParseException("could not parse http request. invalid time value for [{}] field", pe, currentFieldName);
}
} else if (token == XContentParser.Token.START_OBJECT) {
if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.HEADERS)) {
@ -225,7 +225,7 @@ public class HttpRequest implements ToXContent {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.BODY)) {
builder.body(parser.text());
} else {
throw new ParseException("could not parse http request. unexpected object field [{}]", currentFieldName);
throw new ElasticsearchParseException("could not parse http request. unexpected object field [{}]", currentFieldName);
}
} else if (token == XContentParser.Token.VALUE_STRING) {
if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.SCHEME)) {
@ -239,40 +239,29 @@ public class HttpRequest implements ToXContent {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.BODY)) {
builder.body(parser.text());
} else {
throw new ParseException("could not parse http request. unexpected string field [{}]", currentFieldName);
throw new ElasticsearchParseException("could not parse http request. unexpected string field [{}]", currentFieldName);
}
} else if (token == XContentParser.Token.VALUE_NUMBER) {
if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.PORT)) {
builder.port = parser.intValue();
} else {
throw new ParseException("could not parse http request. unexpected numeric field [{}]", currentFieldName);
throw new ElasticsearchParseException("could not parse http request. unexpected numeric field [{}]", currentFieldName);
}
} else {
throw new ParseException("could not parse http request. unexpected token [{}]", token);
throw new ElasticsearchParseException("could not parse http request. unexpected token [{}]", token);
}
}
if (builder.host == null) {
throw new ParseException("could not parse http request. missing required [{}] field", Field.HOST.getPreferredName());
throw new ElasticsearchParseException("could not parse http request. missing required [{}] field", Field.HOST.getPreferredName());
}
if (builder.port < 0) {
throw new ParseException("could not parse http request. missing required [{}] field", Field.PORT.getPreferredName());
throw new ElasticsearchParseException("could not parse http request. missing required [{}] field", Field.PORT.getPreferredName());
}
return builder.build();
}
public static class ParseException extends WatcherException {
public ParseException(String msg, Object... args) {
super(msg, args);
}
public ParseException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}
}
public static class Builder {

View File

@ -6,6 +6,7 @@
package org.elasticsearch.watcher.support.http;
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.collect.MapBuilder;
@ -14,7 +15,6 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.support.WatcherDateTimeUtils;
import org.elasticsearch.watcher.support.http.HttpRequest.Field;
import org.elasticsearch.watcher.support.http.auth.HttpAuth;
@ -27,8 +27,6 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
/**
*/
public class HttpRequestTemplate implements ToXContent {
@ -256,20 +254,20 @@ public class HttpRequestTemplate implements ToXContent {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.CONNECTION_TIMEOUT)) {
try {
builder.connectionTimeout(WatcherDateTimeUtils.parseTimeValue(parser, Field.CONNECTION_TIMEOUT.toString()));
} catch (WatcherDateTimeUtils.ParseException pe) {
throw new ParseException("could not parse http request template. invalid time value for [{}] field", pe, currentFieldName);
} catch (ElasticsearchParseException pe) {
throw new ElasticsearchParseException("could not parse http request template. invalid time value for [{}] field", pe, currentFieldName);
}
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.READ_TIMEOUT)) {
try {
builder.readTimeout(WatcherDateTimeUtils.parseTimeValue(parser, Field.READ_TIMEOUT.toString()));
} catch (WatcherDateTimeUtils.ParseException pe) {
throw new ParseException("could not parse http request template. invalid time value for [{}] field", pe, currentFieldName);
} catch (ElasticsearchParseException pe) {
throw new ElasticsearchParseException("could not parse http request template. invalid time value for [{}] field", pe, currentFieldName);
}
} else if (token == XContentParser.Token.START_OBJECT) {
if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.AUTH)) {
builder.auth(httpAuthRegistry.parse(parser));
} else {
throw new ParseException("could not parse http request template. unexpected object field [{}]", currentFieldName);
throw new ElasticsearchParseException("could not parse http request template. unexpected object field [{}]", currentFieldName);
}
} else if (token == XContentParser.Token.VALUE_STRING) {
if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.SCHEME)) {
@ -279,24 +277,24 @@ public class HttpRequestTemplate implements ToXContent {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.HOST)) {
builder.host = parser.text();
} else {
throw new ParseException("could not parse http request template. unexpected string field [{}]", currentFieldName);
throw new ElasticsearchParseException("could not parse http request template. unexpected string field [{}]", currentFieldName);
}
} else if (token == XContentParser.Token.VALUE_NUMBER) {
if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.PORT)) {
builder.port = parser.intValue();
} else {
throw new ParseException("could not parse http request template. unexpected numeric field [{}]", currentFieldName);
throw new ElasticsearchParseException("could not parse http request template. unexpected numeric field [{}]", currentFieldName);
}
} else {
throw new ParseException("could not parse http request template. unexpected token [{}] for field [{}]", token, currentFieldName);
throw new ElasticsearchParseException("could not parse http request template. unexpected token [{}] for field [{}]", token, currentFieldName);
}
}
if (builder.host == null) {
throw new ParseException("could not parse http request template. missing required [{}] string field", Field.HOST.getPreferredName());
throw new ElasticsearchParseException("could not parse http request template. missing required [{}] string field", Field.HOST.getPreferredName());
}
if (builder.port <= 0) {
throw new ParseException("could not parse http request template. missing required [{}] numeric field", Field.PORT.getPreferredName());
throw new ElasticsearchParseException("could not parse http request template. missing required [{}] numeric field", Field.PORT.getPreferredName());
}
return builder.build();
@ -305,8 +303,8 @@ public class HttpRequestTemplate implements ToXContent {
private static Template parseFieldTemplate(String field, XContentParser parser) throws IOException {
try {
return Template.parse(parser);
} catch (ParseException pe) {
throw new ParseException("could not parse http request template. could not parse value for [{}] field", pe, field);
} catch (ElasticsearchParseException pe) {
throw new ElasticsearchParseException("could not parse http request template. could not parse value for [{}] field", pe, field);
}
}
@ -324,18 +322,6 @@ public class HttpRequestTemplate implements ToXContent {
}
return templates;
}
}
public static class ParseException extends WatcherException {
public ParseException(String msg, Object... args) {
super(msg, args);
}
public ParseException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}
public static class Builder {
@ -429,14 +415,6 @@ public class HttpRequestTemplate implements ToXContent {
return this;
}
public Builder body(ToXContent content) {
try {
return body(jsonBuilder().value(content));
} catch (IOException ioe) {
throw new WatcherException("could not set http input body to given xcontent", ioe);
}
}
public Builder body(XContentBuilder content) {
return body(Template.inline(content));
}

View File

@ -6,6 +6,7 @@
package org.elasticsearch.watcher.support.http;
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.bytes.BytesArray;
@ -14,7 +15,6 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.watcher.WatcherException;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import javax.annotation.Nullable;
@ -141,18 +141,18 @@ public class HttpResponse implements ToXContent {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (currentFieldName == null) {
throw new ParseException("could not parse http response. expected a field name but found [{}] instead", token);
throw new ElasticsearchParseException("could not parse http response. expected a field name but found [{}] instead", token);
} else if (token == XContentParser.Token.VALUE_NUMBER) {
if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.STATUS)) {
status = parser.intValue();
} else {
throw new ParseException("could not parse http response. unknown numeric field [{}]", currentFieldName);
throw new ElasticsearchParseException("could not parse http response. unknown numeric field [{}]", currentFieldName);
}
} else if (token == XContentParser.Token.VALUE_STRING) {
if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.BODY)) {
body = parser.text();
} else {
throw new ParseException("could not parse http response. unknown string field [{}]", currentFieldName);
throw new ElasticsearchParseException("could not parse http response. unknown string field [{}]", currentFieldName);
}
} else if (token == XContentParser.Token.START_OBJECT) {
String headerName = null;
@ -160,14 +160,14 @@ public class HttpResponse implements ToXContent {
if (token == XContentParser.Token.FIELD_NAME) {
headerName = parser.currentName();
} else if (headerName == null){
throw new ParseException("could not parse http response. expected a header name but found [{}] instead", token);
throw new ElasticsearchParseException("could not parse http response. expected a header name but found [{}] instead", token);
} else if (token.isValue()) {
headers.put(headerName, new String[] { String.valueOf(parser.objectText()) });
} else if (token == XContentParser.Token.START_ARRAY) {
List<String> values = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
if (!token.isValue()) {
throw new ParseException("could not parse http response. expected a header value for header [{}] but found [{}] instead", headerName, token);
throw new ElasticsearchParseException("could not parse http response. expected a header value for header [{}] but found [{}] instead", headerName, token);
} else {
values.add(String.valueOf(parser.objectText()));
}
@ -176,26 +176,16 @@ public class HttpResponse implements ToXContent {
}
}
} else {
throw new ParseException("could not parse http response. unexpected token [{}]", token);
throw new ElasticsearchParseException("could not parse http response. unexpected token [{}]", token);
}
}
if (status < 0) {
throw new ParseException("could not parse http response. missing required numeric [{}] field holding the response's http status code", Field.STATUS.getPreferredName());
throw new ElasticsearchParseException("could not parse http response. missing required numeric [{}] field holding the response's http status code", Field.STATUS.getPreferredName());
}
return new HttpResponse(status, body, headers.build());
}
public static class ParseException extends WatcherException {
public ParseException(String msg, Object... args) {
super(msg, args);
}
public ParseException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}
interface Field {
ParseField STATUS = new ParseField("status");
ParseField HEADERS = new ParseField("headers");

View File

@ -1,21 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.support.http.auth;
import org.elasticsearch.watcher.WatcherException;
/**
*/
public class HttpAuthException extends WatcherException {
public HttpAuthException(String msg, Object... args) {
super(msg, args);
}
public HttpAuthException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -6,12 +6,15 @@
package org.elasticsearch.watcher.support.http.auth;
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Map;
import static org.elasticsearch.watcher.support.Exceptions.illegalArgument;
/**
*
*/
@ -34,7 +37,7 @@ public class HttpAuthRegistry {
} else if (token == XContentParser.Token.START_OBJECT && type != null) {
HttpAuthFactory factory = factories.get(type);
if (factory == null) {
throw new HttpAuthException("unknown http auth type [" + type + "]");
throw new ElasticsearchParseException("unknown http auth type [{}]", type);
}
auth = factory.parse(parser);
}
@ -45,7 +48,7 @@ public class HttpAuthRegistry {
public <A extends HttpAuth, AA extends ApplicableHttpAuth<A>> AA createApplicable(A auth) {
HttpAuthFactory factory = factories.get(auth.type());
if (factory == null) {
throw new HttpAuthException("unknown http auth type [{}]", auth.type());
throw illegalArgument("unknown http auth type [{}]", auth.type());
}
return (AA) factory.createApplicable(auth);
}

View File

@ -10,7 +10,6 @@ import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.support.http.auth.HttpAuth;
import org.elasticsearch.watcher.support.http.auth.HttpAuthException;
import org.elasticsearch.watcher.support.secret.Secret;
import org.elasticsearch.watcher.support.secret.SensitiveXContentParser;
import org.elasticsearch.watcher.support.xcontent.WatcherParams;
@ -96,10 +95,10 @@ public class BasicAuth implements HttpAuth {
}
if (username == null) {
throw new HttpAuthException("username is a required option");
throw new ElasticsearchParseException("username is a required option");
}
if (password == null) {
throw new HttpAuthException("password is a required option");
throw new ElasticsearchParseException("password is a required option");
}
return new BasicAuth(username, password);

View File

@ -5,13 +5,13 @@
*/
package org.elasticsearch.watcher.support.template;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.xcontent.*;
import org.elasticsearch.script.ScriptService.ScriptType;
import org.elasticsearch.watcher.WatcherException;
import java.io.IOException;
import java.util.Collections;
@ -94,11 +94,9 @@ public class Template implements ToXContent {
case FILE:
builder.field(Field.FILE.getPreferredName(), template);
break;
case INDEXED:
default: // INDEXED
assert type == ScriptType.INDEXED : "template type [" + type + "] is not supported";
builder.field(Field.ID.getPreferredName(), template);
break;
default:
throw new WatcherException("unsupported script type [{}]", type);
}
if (this.params != null) {
builder.field(Field.PARAMS.getPreferredName(), this.params);
@ -112,7 +110,7 @@ public class Template implements ToXContent {
return new Template(String.valueOf(parser.objectText()));
}
if (token != XContentParser.Token.START_OBJECT) {
throw new ParseException("expected a string value or an object, but found [{}] instead", token);
throw new ElasticsearchParseException("expected a string value or an object, but found [{}] instead", token);
}
String template = null;
@ -138,27 +136,27 @@ public class Template implements ToXContent {
if (token == XContentParser.Token.VALUE_STRING) {
template = parser.text();
} else {
throw new ParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token);
throw new ElasticsearchParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token);
}
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.ID)) {
type = ScriptType.INDEXED;
if (token == XContentParser.Token.VALUE_STRING) {
template = parser.text();
} else {
throw new ParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token);
throw new ElasticsearchParseException("expected a string value for field [{}], but found [{}]", currentFieldName, token);
}
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.PARAMS)) {
if (token == XContentParser.Token.START_OBJECT) {
params = parser.map();
} else {
throw new ParseException("expected an object for field [{}], but found [{}]", currentFieldName, token);
throw new ElasticsearchParseException("expected an object for field [{}], but found [{}]", currentFieldName, token);
}
} else {
throw new ParseException("unexpected field [{}]", currentFieldName);
throw new ElasticsearchParseException("unexpected field [{}]", currentFieldName);
}
}
if (template == null) {
throw new ParseException("expected one of [{}], [{}] or [{}] fields, but found none", Field.INLINE.getPreferredName(), Field.FILE.getPreferredName(), Field.ID.getPreferredName());
throw new ElasticsearchParseException("expected one of [{}], [{}] or [{}] fields, but found none", Field.INLINE.getPreferredName(), Field.FILE.getPreferredName(), Field.ID.getPreferredName());
}
assert type != null : "if template is not null, type should definitely not be null";
return new Template(template, contentType, type, params);
@ -258,17 +256,6 @@ public class Template implements ToXContent {
}
}
public static class ParseException extends WatcherException {
public ParseException(String msg, Object... args) {
super(msg, args);
}
public ParseException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}
public interface Field {
ParseField INLINE = new ParseField("inline");
ParseField FILE = new ParseField("file");

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.support.template;
import org.elasticsearch.watcher.WatcherException;
/**
*
*/
public class TemplateException extends WatcherException {
public TemplateException(String msg) {
super(msg);
}
public TemplateException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@ -1,29 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.support.validation;
import org.elasticsearch.watcher.WatcherException;
/**
*
*/
public class WatcherSettingsException extends WatcherException {
public WatcherSettingsException() {
super("invalid settings");
}
public void addError(String error) {
addSuppressed(new InvalidSettingException(error));
}
static class InvalidSettingException extends WatcherException {
public InvalidSettingException(String error) {
super(error);
}
}
}

View File

@ -10,8 +10,10 @@ import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.support.LoggerMessageFormat;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.watcher.support.Exceptions;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
/**
*
@ -46,10 +48,10 @@ public class WatcherSettingsValidation extends AbstractLifecycleComponent<Watche
if (errors.isEmpty()) {
return;
}
WatcherSettingsException exception = new WatcherSettingsException();
StringBuilder sb = new StringBuilder("encountered invalid watcher settings:\n");
for (String error : errors) {
exception.addError(error);
sb.append("- ").append(error).append("\n");
}
throw exception;
throw Exceptions.invalidSettings(sb.toString());
}
}

View File

@ -41,9 +41,13 @@ public interface Transform extends ToXContent {
}
public Result(String type, Exception e) {
this(type, ExceptionsHelper.detailedMessage(e));
}
public Result(String type, String errorMessage) {
this.type = type;
this.status = Status.FAILURE;
this.reason = ExceptionsHelper.detailedMessage(e);
this.reason = errorMessage;
this.payload = null;
}

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.transform;
import org.elasticsearch.watcher.WatcherException;
/**
*
*/
public class TransformException extends WatcherException {
public TransformException(String msg, Object... args) {
super(msg, args);
}
public TransformException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -6,6 +6,7 @@
package org.elasticsearch.watcher.transform;
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.xcontent.XContentParser;
@ -45,7 +46,7 @@ public class TransformRegistry {
public ExecutableTransform parse(String watchId, String type, XContentParser parser) throws IOException {
TransformFactory factory = factories.get(type);
if (factory == null) {
throw new TransformException("could not parse transform for watch [{}], unknown transform type [{}]", watchId, type);
throw new ElasticsearchParseException("could not parse transform for watch [{}], unknown transform type [{}]", watchId, type);
}
return factory.parseExecutable(watchId, parser);
}
@ -53,7 +54,7 @@ public class TransformRegistry {
public Transform parseTransform(String watchId, String type, XContentParser parser) throws IOException {
TransformFactory factory = factories.get(type);
if (factory == null) {
throw new TransformException("could not parse transform for watch [{}], unknown transform type [{}]", watchId, type);
throw new ElasticsearchParseException("could not parse transform for watch [{}], unknown transform type [{}]", watchId, type);
}
return factory.parseTransform(watchId, parser);
}

View File

@ -6,6 +6,7 @@
package org.elasticsearch.watcher.transform.chain;
import com.google.common.collect.ImmutableList;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
@ -67,7 +68,7 @@ public class ChainTransform implements Transform {
public static ChainTransform parse(String watchId, XContentParser parser, TransformRegistry transformRegistry) throws IOException {
XContentParser.Token token = parser.currentToken();
if (token != XContentParser.Token.START_ARRAY) {
throw new ChainTransformException("could not parse [{}] transform for watch [{}]. expected an array of transform objects, but found [{}] instead", TYPE, watchId, token);
throw new ElasticsearchParseException("could not parse [{}] transform for watch [{}]. expected an array of transform objects, but found [{}] instead", TYPE, watchId, token);
}
ImmutableList.Builder<Transform> builder = ImmutableList.builder();
@ -75,7 +76,7 @@ public class ChainTransform implements Transform {
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
if (token != XContentParser.Token.START_OBJECT) {
throw new ChainTransformException("could not parse [{}] transform for watch [{}]. expected a transform object, but found [{}] instead", TYPE, watchId, token);
throw new ElasticsearchParseException("could not parse [{}] transform for watch [{}]. expected a transform object, but found [{}] instead", TYPE, watchId, token);
}
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
@ -106,6 +107,11 @@ public class ChainTransform implements Transform {
this.results = results;
}
public Result(String errorMessage, ImmutableList<Transform.Result> results) {
super(TYPE, errorMessage);
this.results = results;
}
public ImmutableList<Transform.Result> results() {
return results;
}

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.transform.chain;
import org.elasticsearch.watcher.transform.TransformException;
/**
*
*/
public class ChainTransformException extends TransformException {
public ChainTransformException(String msg, Object... args) {
super(msg, args);
}
public ChainTransformException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -15,6 +15,8 @@ import org.elasticsearch.watcher.watch.Payload;
import java.io.IOException;
import java.util.List;
import static org.elasticsearch.common.logging.support.LoggerMessageFormat.format;
/**
*
*/
@ -48,7 +50,7 @@ public class ExecutableChainTransform extends ExecutableTransform<ChainTransform
Transform.Result result = transform.execute(ctx, payload);
results.add(result);
if (result.status() == Transform.Result.Status.FAILURE) {
throw new ChainTransformException("failed to execute [{}] transform. failed to execute sub-transform [{}]", ChainTransform.TYPE, transform.type());
return new ChainTransform.Result(format("failed to execute [{}] transform for [{}]. failed to execute sub-transform [{}]", ChainTransform.TYPE, ctx.id(), transform.type()), results.build());
}
payload = result.payload();
}

View File

@ -9,6 +9,7 @@ import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.script.CompiledScript;
import org.elasticsearch.script.ExecutableScript;
import org.elasticsearch.watcher.execution.WatchExecutionContext;
import org.elasticsearch.watcher.support.Exceptions;
import org.elasticsearch.watcher.support.Script;
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
import org.elasticsearch.watcher.transform.ExecutableTransform;
@ -18,6 +19,7 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static org.elasticsearch.watcher.support.Exceptions.invalidScript;
import static org.elasticsearch.watcher.support.Variables.createCtxModel;
/**
@ -35,7 +37,7 @@ public class ExecutableScriptTransform extends ExecutableTransform<ScriptTransfo
try {
compiledScript = scriptService.compile(script);
} catch (Exception e) {
throw new ScriptTransformValidationException("failed to compile script [{}] with lang [{}] of type [{}]", e, script.script(), script.lang(), script.type(), e);
throw invalidScript("failed to compile script [{}] with lang [{}] of type [{}]", e, script.script(), script.lang(), script.type(), e);
}
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.transform.script;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.support.Script;
@ -59,8 +60,8 @@ public class ScriptTransform implements Transform {
try {
Script script = Script.parse(parser);
return new ScriptTransform(script);
} catch (Script.ParseException pe) {
throw new ScriptTransformException("could not parse [{}] transform for watch [{}]. failed to parse script", pe, TYPE, watchId);
} catch (ElasticsearchParseException pe) {
throw new ElasticsearchParseException("could not parse [{}] transform for watch [{}]. failed to parse script", pe, TYPE, watchId);
}
}

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.transform.script;
import org.elasticsearch.watcher.transform.TransformException;
/**
*
*/
public class ScriptTransformException extends TransformException {
public ScriptTransformException(String msg, Object... args) {
super(msg, args);
}
public ScriptTransformException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -1,19 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.transform.script;
/**
*/
public class ScriptTransformValidationException extends ScriptTransformException {
public ScriptTransformValidationException(String msg, Object... args) {
super(msg, args);
}
public ScriptTransformValidationException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.watcher.transform.search;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
@ -13,7 +14,6 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.support.SearchRequestEquivalence;
import org.elasticsearch.watcher.support.SearchRequestParseException;
import org.elasticsearch.watcher.support.WatcherDateTimeUtils;
import org.elasticsearch.watcher.support.WatcherUtils;
import org.elasticsearch.watcher.transform.Transform;
@ -104,8 +104,8 @@ public class SearchTransform implements Transform {
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.REQUEST)) {
try {
request = WatcherUtils.readSearchRequest(parser, ExecutableSearchTransform.DEFAULT_SEARCH_TYPE);
} catch (SearchRequestParseException srpe) {
throw new SearchTransformException("could not parse [{}] transform for watch [{}]. failed to parse [{}]", srpe, TYPE, watchId, currentFieldName);
} catch (ElasticsearchParseException srpe) {
throw new ElasticsearchParseException("could not parse [{}] transform for watch [{}]. failed to parse [{}]", srpe, TYPE, watchId, currentFieldName);
}
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.TIMEOUT)) {
timeout = WatcherDateTimeUtils.parseTimeValue(parser, Field.TIMEOUT.toString());
@ -113,15 +113,15 @@ public class SearchTransform implements Transform {
if (token == XContentParser.Token.VALUE_STRING) {
dynamicNameTimeZone = DateTimeZone.forID(parser.text());
} else {
throw new SearchTransformException("could not parse [{}] transform for watch [{}]. failed to parse [{}]. must be a string value (e.g. 'UTC' or '+01:00').", TYPE, watchId, currentFieldName);
throw new ElasticsearchParseException("could not parse [{}] transform for watch [{}]. failed to parse [{}]. must be a string value (e.g. 'UTC' or '+01:00').", TYPE, watchId, currentFieldName);
}
} else {
throw new SearchTransformException("could not parse [{}] transform for watch [{}]. unexpected field [{}]", TYPE, watchId, currentFieldName);
throw new ElasticsearchParseException("could not parse [{}] transform for watch [{}]. unexpected field [{}]", TYPE, watchId, currentFieldName);
}
}
if (request == null) {
throw new SearchTransformException("could not parse [{}] transform for watch [{}]. missing required [{}] field", TYPE, watchId, Field.REQUEST.getPreferredName());
throw new ElasticsearchParseException("could not parse [{}] transform for watch [{}]. missing required [{}] field", TYPE, watchId, Field.REQUEST.getPreferredName());
}
return new SearchTransform(request, timeout, dynamicNameTimeZone);
}

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.transform.search;
import org.elasticsearch.watcher.transform.TransformException;
/**
*
*/
public class SearchTransformException extends TransformException {
public SearchTransformException(String msg, Object... args) {
super(msg, args);
}
public SearchTransformException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}

View File

@ -12,7 +12,7 @@ import org.elasticsearch.action.support.master.MasterNodeRequest;
import org.elasticsearch.action.support.master.TransportMasterNodeAction;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.plugin.core.LicenseExpiredException;
import org.elasticsearch.license.plugin.core.LicenseUtils;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.watcher.license.LicenseService;
@ -34,7 +34,7 @@ public abstract class WatcherTransportAction<Request extends MasterNodeRequest<R
if (licenseService.enabled()) {
super.doExecute(request, listener);
} else {
listener.onFailure(new LicenseExpiredException(LicenseService.FEATURE_NAME));
listener.onFailure(LicenseUtils.newExpirationException(LicenseService.FEATURE_NAME));
}
}
}

View File

@ -13,14 +13,12 @@ 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.xcontent.XContentType;
import org.joda.time.DateTime;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.condition.always.AlwaysCondition;
import org.elasticsearch.watcher.execution.ActionExecutionMode;
import org.elasticsearch.watcher.execution.ExecutionService;
@ -37,10 +35,13 @@ import org.elasticsearch.watcher.trigger.manual.ManualTriggerEvent;
import org.elasticsearch.watcher.watch.Payload;
import org.elasticsearch.watcher.watch.Watch;
import org.elasticsearch.watcher.watch.WatchStore;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import java.util.Map;
import static org.elasticsearch.watcher.support.Exceptions.illegalArgument;
/**
* Performs the watch execution operation.
*/
@ -83,7 +84,8 @@ public class TransportExecuteWatchAction extends WatcherTransportAction<ExecuteW
if (request.getId() != null) {
watch = watchStore.get(request.getId());
if (watch == null) {
throw new WatcherException("watch [{}] does not exist", request.getId());
//todo we need to find a better std exception for this one
throw new ElasticsearchException("watch [{}] does not exist", request.getId());
}
knownWatch = true;
} else if (request.getWatchSource() != null) {
@ -91,7 +93,7 @@ public class TransportExecuteWatchAction extends WatcherTransportAction<ExecuteW
watch = watchParser.parse(ExecuteWatchRequest.INLINE_WATCH_ID, false, request.getWatchSource());
knownWatch = false;
} else {
throw new WatcherException("no watch provided");
throw illegalArgument("no watch provided");
}
String triggerType = watch.trigger().type();

Some files were not shown because too many files have changed in this diff Show More