Centralized all the date xcontent rendering

Original commit: elastic/x-pack-elasticsearch@08248c30cd
This commit is contained in:
uboness 2015-05-03 19:53:30 +03:00
parent d95e068a77
commit b63630496f
6 changed files with 125 additions and 107 deletions

View File

@ -10,9 +10,10 @@ import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.joda.time.DateTime;
import org.elasticsearch.common.joda.time.DateTimeZone;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.core.DateFieldMapper;
import org.elasticsearch.watcher.WatcherSettingsException;
import org.elasticsearch.watcher.WatcherException;
import java.io.IOException;
@ -39,7 +40,8 @@ public class WatcherDateUtils {
return dateTimeFormatter.printer().print(date);
}
public static DateTime parseDate(String fieldName, XContentParser.Token token, XContentParser parser, DateTimeZone timeZone) throws IOException {
public static DateTime parseDate(String fieldName, XContentParser parser, DateTimeZone timeZone) throws IOException {
XContentParser.Token token = parser.currentToken();
if (token == XContentParser.Token.VALUE_NUMBER) {
return new DateTime(parser.longValue(), timeZone);
}
@ -49,8 +51,11 @@ public class WatcherDateUtils {
if (token == XContentParser.Token.VALUE_NULL) {
return null;
}
throw new WatcherSettingsException("could not parse date/time. expected [" + fieldName +
"] to be either a number or a string but was [" + token + "] instead");
throw new ParseException("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 {
return builder.field(fieldName, formatDate(date));
}
public static void writeDate(StreamOutput out, DateTime date) throws IOException {
@ -73,4 +78,10 @@ public class WatcherDateUtils {
public static DateTime readOptionalDate(StreamInput in, DateTimeZone timeZone) throws IOException {
return in.readBoolean() ? new DateTime(in.readLong(), timeZone) : null;
}
public static class ParseException extends WatcherException {
public ParseException(String msg, Object... args) {
super(msg, args);
}
}
}

View File

@ -17,8 +17,6 @@ import java.util.Map;
*/
public abstract class TriggerEvent implements ToXContent {
public static final ParseField TRIGGERED_TIME_FIELD = new ParseField("triggered_time");
private final String jobName;
protected final DateTime triggeredTime;
protected final Map<String, Object> data;
@ -27,7 +25,7 @@ public abstract class TriggerEvent implements ToXContent {
this.jobName = jobName;
this.triggeredTime = triggeredTime;
this.data = new HashMap<>();
data.put(TRIGGERED_TIME_FIELD.getPreferredName(), triggeredTime);
data.put(Field.TRIGGERED_TIME.getPreferredName(), triggeredTime);
}
public String jobName() {
@ -44,4 +42,8 @@ public abstract class TriggerEvent implements ToXContent {
return data;
}
protected interface Field {
ParseField TRIGGERED_TIME = new ParseField("triggered_time");
}
}

View File

@ -22,8 +22,6 @@ import static org.elasticsearch.common.joda.time.DateTimeZone.UTC;
*/
public class ManualTriggerEvent extends TriggerEvent {
private final static ParseField TRIGGER_DATA_FIELD = new ParseField("trigger_data");
private final Map<String, Object> triggerData;
public ManualTriggerEvent(DateTime triggeredTime, Map<String, Object> triggerData) {
@ -43,10 +41,10 @@ public class ManualTriggerEvent extends TriggerEvent {
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject()
.field(TRIGGERED_TIME_FIELD.getPreferredName(), WatcherDateUtils.formatDate(triggeredTime))
.field(TRIGGER_DATA_FIELD.getPreferredName(), triggerData)
.endObject();
builder.startObject();
WatcherDateUtils.writeDate(Field.TRIGGERED_TIME.getPreferredName(), builder, triggeredTime);
builder.field(Field.TRIGGER_DATA.getPreferredName(), triggerData);
return builder.endObject();
}
public static ManualTriggerEvent parse(String context, XContentParser parser) throws IOException {
@ -57,22 +55,20 @@ public class ManualTriggerEvent extends TriggerEvent {
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if (token == XContentParser.Token.VALUE_STRING) {
if (TRIGGERED_TIME_FIELD.match(currentFieldName)) {
triggeredTime = WatcherDateUtils.parseDate(parser.text(), UTC);
} else {
throw new ParseException("could not parse trigger event for [" + context + "]. unknown string value field [" + currentFieldName + "]");
}
} else if (token == XContentParser.Token.START_OBJECT) {
if (TRIGGER_DATA_FIELD.match(currentFieldName)) {
triggerData = parser.map();
} else {
throw new ParseException("could not parse trigger event for [" + context + "]. unknown object value field [" + currentFieldName + "]");
}
} else {
throw new ParseException("could not parse trigger event for [" + context + "]. unexpected token [" + token + "]");
} else if (Field.TRIGGERED_TIME.match(currentFieldName)) {
try {
triggeredTime = WatcherDateUtils.parseDate(currentFieldName, parser, UTC);
} catch (WatcherDateUtils.ParseException pe) {
throw new ParseException("could not parse [{}] trigger event for [{}]. failed to parse date field [{}]", pe, ManualTriggerEngine.TYPE, context, currentFieldName);
}
} else if (token == XContentParser.Token.START_OBJECT) {
if (Field.TRIGGER_DATA.match(currentFieldName)) {
triggerData = parser.map();
} else {
throw new ParseException("could not parse trigger event for [{}]. unexpected object value field [{}]", context, currentFieldName);
}
} else {
throw new ParseException("could not parse trigger event for [{}]. unexpected token [{}]", context, token);
}
}
@ -83,13 +79,17 @@ public class ManualTriggerEvent extends TriggerEvent {
public static class ParseException extends WatcherException {
public ParseException(String msg) {
super(msg);
public ParseException(String msg, Object... args) {
super(msg, args);
}
public ParseException(String msg, Throwable cause) {
super(msg, cause);
public ParseException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}
interface Field extends TriggerEvent.Field {
ParseField TRIGGER_DATA = new ParseField("trigger_data");
}
}

View File

@ -22,8 +22,6 @@ import static org.elasticsearch.common.joda.time.DateTimeZone.UTC;
*/
public class ScheduleTriggerEvent extends TriggerEvent {
public static final ParseField SCHEDULED_TIME_FIELD = new ParseField("scheduled_time");
private final DateTime scheduledTime;
public ScheduleTriggerEvent(DateTime triggeredTime, DateTime scheduledTime) {
@ -33,7 +31,7 @@ public class ScheduleTriggerEvent extends TriggerEvent {
public ScheduleTriggerEvent(String jobName, DateTime triggeredTime, DateTime scheduledTime) {
super(jobName, triggeredTime);
this.scheduledTime = scheduledTime;
data.put(SCHEDULED_TIME_FIELD.getPreferredName(), scheduledTime);
data.put(Field.SCHEDULED_TIME.getPreferredName(), scheduledTime);
}
@Override
@ -47,10 +45,10 @@ public class ScheduleTriggerEvent extends TriggerEvent {
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject()
.field(TRIGGERED_TIME_FIELD.getPreferredName(), WatcherDateUtils.formatDate(triggeredTime))
.field(SCHEDULED_TIME_FIELD.getPreferredName(), WatcherDateUtils.formatDate(scheduledTime))
.endObject();
builder.startObject();
WatcherDateUtils.writeDate(Field.TRIGGERED_TIME.getPreferredName(), builder, triggeredTime);
WatcherDateUtils.writeDate(Field.SCHEDULED_TIME.getPreferredName(), builder, scheduledTime);
return builder.endObject();
}
public static ScheduleTriggerEvent parse(String context, XContentParser parser) throws IOException {
@ -58,22 +56,24 @@ public class ScheduleTriggerEvent extends TriggerEvent {
DateTime scheduledTime = null;
String currentFieldName = null;
XContentParser.Token token = null;
XContentParser.Token token;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if (token == XContentParser.Token.VALUE_STRING) {
if (TRIGGERED_TIME_FIELD.match(currentFieldName)) {
triggeredTime = WatcherDateUtils.parseDate(parser.text(), UTC);
} else if (SCHEDULED_TIME_FIELD.match(currentFieldName)) {
scheduledTime = WatcherDateUtils.parseDate(parser.text(), UTC);
} else {
throw new ParseException("could not parse trigger event for [" + context + "]. unknown string value field [" + currentFieldName + "]");
}
} else {
throw new ParseException("could not parse trigger event for [" + context + "]. unexpected token [" + token + "]");
} else if (Field.TRIGGERED_TIME.match(currentFieldName)) {
try {
triggeredTime = WatcherDateUtils.parseDate(currentFieldName, parser, UTC);
} catch (WatcherDateUtils.ParseException pe) {
throw new ParseException("could not parse [{}] trigger event for [{}]. failed to parse date field [{}]", pe, ScheduleTriggerEngine.TYPE, context, currentFieldName);
}
} else if (Field.SCHEDULED_TIME.match(currentFieldName)) {
try {
scheduledTime = WatcherDateUtils.parseDate(currentFieldName, parser, UTC);
} catch (WatcherDateUtils.ParseException pe) {
throw new ParseException("could not parse [{}] trigger event for [{}]. failed to parse date field [{}]", pe, ScheduleTriggerEngine.TYPE, context, currentFieldName);
}
}else {
throw new ParseException("could not parse trigger event for [{}]. unexpected token [{}]", context, token);
}
}
@ -84,12 +84,16 @@ public class ScheduleTriggerEvent extends TriggerEvent {
public static class ParseException extends WatcherException {
public ParseException(String msg) {
super(msg);
public ParseException(String msg, Object... args) {
super(msg, args);
}
public ParseException(String msg, Throwable cause) {
super(msg, cause);
public ParseException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}
}
interface Field extends TriggerEvent.Field {
ParseField SCHEDULED_TIME = new ParseField("scheduled_time");
}
}

View File

@ -21,7 +21,6 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.watcher.WatcherException;
import org.elasticsearch.watcher.WatcherSettingsException;
import org.elasticsearch.watcher.actions.ActionRegistry;
import org.elasticsearch.watcher.actions.ExecutableActions;
import org.elasticsearch.watcher.condition.ConditionRegistry;
@ -31,9 +30,10 @@ import org.elasticsearch.watcher.input.ExecutableInput;
import org.elasticsearch.watcher.input.InputRegistry;
import org.elasticsearch.watcher.input.none.ExecutableNoneInput;
import org.elasticsearch.watcher.license.LicenseService;
import org.elasticsearch.watcher.support.WatcherDateUtils;
import org.elasticsearch.watcher.support.clock.Clock;
import org.elasticsearch.watcher.support.secret.SensitiveXContentParser;
import org.elasticsearch.watcher.support.secret.SecretService;
import org.elasticsearch.watcher.support.secret.SensitiveXContentParser;
import org.elasticsearch.watcher.throttle.Throttler;
import org.elasticsearch.watcher.throttle.WatchThrottler;
import org.elasticsearch.watcher.transform.ExecutableTransform;
@ -248,7 +248,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
* This method is only called once - when the user adds a new watch. From that moment on, all representations
* of the watch in the system will be use secrets for sensitive data.
*
* @see org.elasticsearch.watcher.WatcherService#putWatch(String, BytesReference)
* @see org.elasticsearch.watcher.WatcherService#putWatch(String, BytesReference, TimeValue)
*/
public Watch parseWithSecrets(String id, boolean includeStatus, BytesReference source) {
return parse(id, includeStatus, true, source);
@ -305,7 +305,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
} else if (META_FIELD.match(currentFieldName)) {
metatdata = parser.map();
} else if (STATUS_FIELD.match(currentFieldName)) {
Status parsedStatus= Status.parse(parser);
Status parsedStatus= Status.parse(id, parser);
if (includeStatus) {
status = parsedStatus;
}
@ -315,18 +315,18 @@ public class Watch implements TriggerEngine.Job, ToXContent {
} else if (token == XContentParser.Token.VALUE_NUMBER) {
throttlePeriod = TimeValue.timeValueMillis(parser.longValue());
} else {
throw new WatcherSettingsException("could not parse watch [" + id + "] throttle period. could not parse token [" + token + "] as time value (must either be string or number)");
throw new WatcherException("could not parse watch [{}] throttle period. could not parse token [{}] as time value (must either be string or number)", id, token);
}
} else {
throw new WatcherSettingsException("could not parse watch [" + id + "]. unexpected field [" + currentFieldName + "]");
throw new WatcherException("could not parse watch [{}]. unexpected field [{}]", id, currentFieldName);
}
}
}
if (trigger == null) {
throw new WatcherSettingsException("could not parse watch [" + id + "]. missing watch trigger");
throw new WatcherException("could not parse watch [{}]. missing required field [{}]", id, TRIGGER_FIELD.getPreferredName());
}
if (actions == null) {
throw new WatcherSettingsException("could not parse watch [" + id + "]. missing watch actions");
throw new WatcherException("could not parse watch [{}]. missing required field [{}]", id, ACTIONS_FIELD.getPreferredName());
}
return new Watch(id, clock, licenseService, trigger, input, condition, transform, actions, metatdata, throttlePeriod, status);
@ -574,7 +574,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
return builder.endObject();
}
public static Status parse(XContentParser parser) throws IOException {
public static Status parse(String id, XContentParser parser) throws IOException {
DateTime lastChecked = null;
DateTime lastMetCondition = null;
@ -588,64 +588,76 @@ public class Watch implements TriggerEngine.Job, ToXContent {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (LAST_CHECKED_FIELD.match(currentFieldName)) {
if (token.isValue()) {
lastChecked = parseDate(currentFieldName, token, parser, UTC);
} else {
throw new WatcherException("expecting field [" + currentFieldName + "] to hold a date value, found [" + token + "] instead");
try {
lastChecked = WatcherDateUtils.parseDate(currentFieldName, parser, UTC);
} catch (WatcherDateUtils.ParseException pe) {
throw new WatcherException("could not parse watch [{}]. failed to parse date field [{}]", pe, id, currentFieldName);
}
} else if (LAST_MET_CONDITION_FIELD.match(currentFieldName)) {
if (token.isValue()) {
lastMetCondition = parseDate(currentFieldName, token, parser, UTC);
} else {
throw new WatcherException("expecting field [" + currentFieldName + "] to hold a date value, found [" + token + "] instead");
try {
lastMetCondition = WatcherDateUtils.parseDate(currentFieldName, parser, UTC);
} catch (WatcherDateUtils.ParseException pe) {
throw new WatcherException("could not parse watch [{}]. failed to parse date field [{}]", pe, id, currentFieldName);
}
} else if (LAST_EXECUTED_FIELD.match(currentFieldName)) {
if (token.isValue()) {
lastExecuted = parseDate(currentFieldName, token, parser, UTC);
} else {
throw new WatcherException("expecting field [" + currentFieldName + "] to hold a date value, found [" + token + "] instead");
try {
lastExecuted = WatcherDateUtils.parseDate(currentFieldName, parser, UTC);
} catch (WatcherDateUtils.ParseException pe) {
throw new WatcherException("could not parse watch [{}]. failed to parse date field [{}]", pe, id, currentFieldName);
}
} else if (LAST_THROTTLED_FIELD.match(currentFieldName)) {
String context = currentFieldName;
if (token == XContentParser.Token.START_OBJECT) {
DateTime timestamp = null;
String reason = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token.isValue()) {
if (TIMESTAMP_FIELD.match(currentFieldName)) {
timestamp = parseDate(currentFieldName, token, parser, UTC);
} else if (REASON_FIELD.match(currentFieldName)) {
} else if (TIMESTAMP_FIELD.match(currentFieldName)) {
try {
timestamp = WatcherDateUtils.parseDate(currentFieldName, parser, UTC);
} catch (WatcherDateUtils.ParseException pe) {
throw new WatcherException("could not parse watch [{}]. failed to parse date field [{}.{}].", pe, id, context, currentFieldName);
}
} else if (token == XContentParser.Token.VALUE_STRING) {
if (REASON_FIELD.match(currentFieldName)) {
reason = parser.text();
} else {
throw new WatcherException("unknown field [" + currentFieldName + "] in watch status throttle entry");
throw new WatcherException("could not parse watch [{}]. unexpected string field [{}.{}]", id, context, currentFieldName);
}
} else {
throw new WatcherException("could not parse watch [{}]. unexpected token [{}] under [{}]", id, token, context);
}
}
lastThrottle = new Throttle(timestamp, reason);
} else {
throw new WatcherException("expecting field [" + currentFieldName + "] to be an object, found [" + token + "] instead");
throw new WatcherException("could not parse watch [{}]. unexpected token [{}] under [{}]", id, token, context);
}
} else if (ACK_FIELD.match(currentFieldName)) {
String context = currentFieldName;
if (token == XContentParser.Token.START_OBJECT) {
AckStatus.State state = null;
DateTime timestamp = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token.isValue()) {
if (TIMESTAMP_FIELD.match(currentFieldName)) {
timestamp = parseDate(currentFieldName, token, parser, UTC);
} else if (STATE_FIELD.match(currentFieldName)) {
} else if (TIMESTAMP_FIELD.match(currentFieldName)) {
try {
timestamp = WatcherDateUtils.parseDate(currentFieldName, parser, UTC);
} catch (WatcherDateUtils.ParseException pe) {
throw new WatcherException("could not parse watch [{}]. failed to parse date field [{}.{}]", pe, id, context, currentFieldName);
}
} else if (token == XContentParser.Token.VALUE_STRING) {
if (STATE_FIELD.match(currentFieldName)) {
state = AckStatus.State.valueOf(parser.text().toUpperCase(Locale.ROOT));
} else {
throw new WatcherException("unknown field [" + currentFieldName + "] in watch status throttle entry");
throw new WatcherException("could not parse watch [{}]. unexpected string field [{}.{}]", id, context, currentFieldName);
}
}
}
ackStatus = new AckStatus(state, timestamp);
} else {
throw new WatcherException("expecting field [" + currentFieldName + "] to be an object, found [" + token + "] instead");
throw new WatcherException("could not parse watch [{}]. unexpected token [{}] under [{}] field", id, token, context);
}
}
}
@ -656,7 +668,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
public static class AckStatus {
public static enum State {
public enum State {
AWAITS_EXECUTION,
ACKABLE,
ACKED

View File

@ -82,12 +82,7 @@ public class WatchExecutionResult implements ToXContent {
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
if (builder.humanReadable()) {
builder.field(Parser.EXECUTION_TIME_FIELD.getPreferredName(), WatcherDateUtils.formatDate(executionTime));
} else {
builder.field(Parser.EXECUTION_TIME_FIELD.getPreferredName(), executionTime.getMillis());
}
WatcherDateUtils.writeDate(Parser.EXECUTION_TIME_FIELD.getPreferredName(), builder, executionTime);
if (inputResult != null) {
builder.startObject(Parser.INPUT_RESULT_FIELD.getPreferredName())
.field(inputResult.type(), inputResult, params)
@ -142,23 +137,17 @@ public class WatchExecutionResult implements ToXContent {
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (EXECUTION_TIME_FIELD.match(currentFieldName)) {
try {
executionTime = WatcherDateUtils.parseDate(currentFieldName, parser, UTC);
} catch (WatcherDateUtils.ParseException pe) {
throw new WatcherException("unable to parse watch execution [{}]. failed to parse date field [{}]", pe, wid, currentFieldName);
}
} else if (token.isValue()) {
if (THROTTLE_REASON.match(currentFieldName)) {
throttleReason = parser.text();
} else if (THROTTLED.match(currentFieldName)) {
throttled = parser.booleanValue();
} else if (EXECUTION_TIME_FIELD.match(currentFieldName)) {
if (token == XContentParser.Token.VALUE_STRING) {
try {
executionTime = WatcherDateUtils.parseDate(parser.text());
} catch (IllegalArgumentException iae) {
throw new WatcherException("unable to parse watch execution [{}]. failed to parse date field [{}]", iae, wid, currentFieldName);
}
} else if (token == XContentParser.Token.VALUE_NUMBER){
executionTime = new DateTime(parser.longValue(), UTC);
} else {
throw new WatcherException("unable to parse watch execution [{}]. failed to parse date field [{}]. expected either a string or a numeric value", wid, currentFieldName);
}
} else {
throw new WatcherException("unable to parse watch execution [{}]. unexpected field [{}]", wid, currentFieldName);
}