Cleanup: Remove HaltedClock (elastic/x-pack-elasticsearch#3731)
java.time features it's own halted clock, called a fixed clock, we can use that one. On top of that the watcher xcontent parser does not need a clock at all, just a timestamp when parsing happened. Original commit: elastic/x-pack-elasticsearch@2061aeffe1
This commit is contained in:
parent
3102b94946
commit
064a0819d9
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.common.time;
|
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
|
||||||
import org.joda.time.DateTimeZone;
|
|
||||||
|
|
||||||
import java.time.Clock;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.ZoneOffset;
|
|
||||||
|
|
||||||
public class HaltedClock extends Clock {
|
|
||||||
|
|
||||||
private final DateTime now;
|
|
||||||
|
|
||||||
public HaltedClock(DateTime now) {
|
|
||||||
this.now = now.toDateTime(DateTimeZone.UTC);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ZoneId getZone() {
|
|
||||||
return ZoneOffset.UTC;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Clock withZone(ZoneId zoneId) {
|
|
||||||
if (zoneId.equals(ZoneOffset.UTC)) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Halted clock time zone cannot be changed");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long millis() {
|
|
||||||
return now.getMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Instant instant() {
|
|
||||||
return Instant.ofEpochMilli(now.getMillis());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -15,6 +15,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.common.xcontent.XContentType;
|
import org.elasticsearch.common.xcontent.XContentType;
|
||||||
import org.elasticsearch.xpack.core.watcher.common.secret.Secret;
|
import org.elasticsearch.xpack.core.watcher.common.secret.Secret;
|
||||||
import org.elasticsearch.xpack.core.watcher.crypto.CryptoService;
|
import org.elasticsearch.xpack.core.watcher.crypto.CryptoService;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
|
@ -59,24 +60,17 @@ public class WatcherXContentParser implements XContentParser {
|
||||||
return new Secret(chars);
|
return new Secret(chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Clock clock(XContentParser parser) {
|
private final DateTime parseTime;
|
||||||
if (parser instanceof WatcherXContentParser) {
|
|
||||||
return ((WatcherXContentParser) parser).getClock();
|
|
||||||
}
|
|
||||||
return Clock.systemUTC();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Clock clock;
|
|
||||||
private final XContentParser parser;
|
private final XContentParser parser;
|
||||||
@Nullable private final CryptoService cryptoService;
|
@Nullable private final CryptoService cryptoService;
|
||||||
|
|
||||||
public WatcherXContentParser(XContentParser parser, Clock clock, @Nullable CryptoService cryptoService) {
|
public WatcherXContentParser(XContentParser parser, DateTime parseTime, @Nullable CryptoService cryptoService) {
|
||||||
this.clock = clock;
|
this.parseTime = parseTime;
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
this.cryptoService = cryptoService;
|
this.cryptoService = cryptoService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Clock getClock() { return clock; }
|
public DateTime getParseDateTime() { return parseTime; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XContentType contentType() {
|
public XContentType contentType() {
|
||||||
|
|
|
@ -22,7 +22,6 @@ import org.elasticsearch.xpack.core.watcher.support.xcontent.WatcherXContentPars
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Clock;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -273,7 +272,7 @@ public class WatchStatus implements ToXContentObject, Streamable {
|
||||||
return builder.endObject();
|
return builder.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WatchStatus parse(String watchId, XContentParser parser, Clock clock) throws IOException {
|
public static WatchStatus parse(String watchId, WatcherXContentParser parser) throws IOException {
|
||||||
State state = null;
|
State state = null;
|
||||||
ExecutionState executionState = null;
|
ExecutionState executionState = null;
|
||||||
DateTime lastChecked = null;
|
DateTime lastChecked = null;
|
||||||
|
@ -289,7 +288,7 @@ public class WatchStatus implements ToXContentObject, Streamable {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else if (Field.STATE.match(currentFieldName)) {
|
} else if (Field.STATE.match(currentFieldName)) {
|
||||||
try {
|
try {
|
||||||
state = State.parse(parser, clock);
|
state = State.parse(parser);
|
||||||
} catch (ElasticsearchParseException e) {
|
} catch (ElasticsearchParseException e) {
|
||||||
throw new ElasticsearchParseException("could not parse watch status for [{}]. failed to parse field [{}]",
|
throw new ElasticsearchParseException("could not parse watch status for [{}]. failed to parse field [{}]",
|
||||||
e, watchId, currentFieldName);
|
e, watchId, currentFieldName);
|
||||||
|
@ -348,7 +347,7 @@ public class WatchStatus implements ToXContentObject, Streamable {
|
||||||
// this is to support old watches that weren't upgraded yet to
|
// this is to support old watches that weren't upgraded yet to
|
||||||
// contain the state
|
// contain the state
|
||||||
if (state == null) {
|
if (state == null) {
|
||||||
state = new State(true, new DateTime(WatcherXContentParser.clock(parser).millis(), UTC));
|
state = new State(true, parser.getParseDateTime());
|
||||||
}
|
}
|
||||||
actions = actions == null ? emptyMap() : unmodifiableMap(actions);
|
actions = actions == null ? emptyMap() : unmodifiableMap(actions);
|
||||||
|
|
||||||
|
@ -381,12 +380,12 @@ public class WatchStatus implements ToXContentObject, Streamable {
|
||||||
return builder.endObject();
|
return builder.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static State parse(XContentParser parser, Clock clock) throws IOException {
|
public static State parse(XContentParser parser) throws IOException {
|
||||||
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
|
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
|
||||||
throw new ElasticsearchParseException("expected an object but found [{}] instead", parser.currentToken());
|
throw new ElasticsearchParseException("expected an object but found [{}] instead", parser.currentToken());
|
||||||
}
|
}
|
||||||
boolean active = true;
|
boolean active = true;
|
||||||
DateTime timestamp = new DateTime(clock.millis(), UTC);
|
DateTime timestamp = DateTime.now(UTC);
|
||||||
String currentFieldName = null;
|
String currentFieldName = null;
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
|
|
|
@ -6,11 +6,10 @@
|
||||||
package org.elasticsearch.xpack.security.authc.saml;
|
package org.elasticsearch.xpack.security.authc.saml;
|
||||||
|
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.common.time.HaltedClock;
|
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.joda.time.DateTime;
|
|
||||||
import org.joda.time.DateTimeZone;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.opensaml.saml.common.xml.SAMLConstants;
|
import org.opensaml.saml.common.xml.SAMLConstants;
|
||||||
import org.opensaml.saml.saml2.core.LogoutRequest;
|
import org.opensaml.saml.saml2.core.LogoutRequest;
|
||||||
|
@ -67,8 +66,8 @@ public class SamlLogoutRequestMessageBuilderTests extends SamlTestCase {
|
||||||
"http://idp.example.com/saml/logout/artifact");
|
"http://idp.example.com/saml/logout/artifact");
|
||||||
idpRole.getSingleLogoutServices().add(sloArtifact);
|
idpRole.getSingleLogoutServices().add(sloArtifact);
|
||||||
|
|
||||||
final DateTime now = DateTime.now(DateTimeZone.UTC);
|
Clock fixedClock = Clock.fixed(Instant.now(), ZoneOffset.UTC);
|
||||||
final SamlLogoutRequestMessageBuilder builder = new SamlLogoutRequestMessageBuilder(new HaltedClock(now), sp, idp, nameId, session);
|
final SamlLogoutRequestMessageBuilder builder = new SamlLogoutRequestMessageBuilder(fixedClock, sp, idp, nameId, session);
|
||||||
final LogoutRequest logoutRequest = builder.build();
|
final LogoutRequest logoutRequest = builder.build();
|
||||||
assertThat(logoutRequest, notNullValue());
|
assertThat(logoutRequest, notNullValue());
|
||||||
assertThat(logoutRequest.getReason(), nullValue());
|
assertThat(logoutRequest.getReason(), nullValue());
|
||||||
|
@ -82,7 +81,7 @@ public class SamlLogoutRequestMessageBuilderTests extends SamlTestCase {
|
||||||
assertThat(logoutRequest.getConsent(), nullValue());
|
assertThat(logoutRequest.getConsent(), nullValue());
|
||||||
assertThat(logoutRequest.getNotOnOrAfter(), nullValue());
|
assertThat(logoutRequest.getNotOnOrAfter(), nullValue());
|
||||||
assertThat(logoutRequest.getIssueInstant(), notNullValue());
|
assertThat(logoutRequest.getIssueInstant(), notNullValue());
|
||||||
assertThat(logoutRequest.getIssueInstant(), equalTo(now));
|
assertThat(logoutRequest.getIssueInstant().getMillis(), equalTo(fixedClock.millis()));
|
||||||
assertThat(logoutRequest.getSessionIndexes(), iterableWithSize(1));
|
assertThat(logoutRequest.getSessionIndexes(), iterableWithSize(1));
|
||||||
assertThat(logoutRequest.getSessionIndexes().get(0).getSessionIndex(), equalTo(session));
|
assertThat(logoutRequest.getSessionIndexes().get(0).getSessionIndex(), equalTo(session));
|
||||||
assertThat(logoutRequest.getDestination(), equalTo("http://idp.example.com/saml/logout/redirect"));
|
assertThat(logoutRequest.getDestination(), equalTo("http://idp.example.com/saml/logout/redirect"));
|
||||||
|
|
|
@ -32,7 +32,6 @@ import org.elasticsearch.xpack.watcher.condition.InternalAlwaysCondition;
|
||||||
import org.elasticsearch.xpack.watcher.input.InputRegistry;
|
import org.elasticsearch.xpack.watcher.input.InputRegistry;
|
||||||
import org.elasticsearch.xpack.watcher.input.none.ExecutableNoneInput;
|
import org.elasticsearch.xpack.watcher.input.none.ExecutableNoneInput;
|
||||||
import org.elasticsearch.xpack.watcher.trigger.TriggerService;
|
import org.elasticsearch.xpack.watcher.trigger.TriggerService;
|
||||||
import org.elasticsearch.xpack.common.time.HaltedClock;
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -53,23 +52,22 @@ public class WatchParser extends AbstractComponent {
|
||||||
private final ActionRegistry actionRegistry;
|
private final ActionRegistry actionRegistry;
|
||||||
private final InputRegistry inputRegistry;
|
private final InputRegistry inputRegistry;
|
||||||
private final CryptoService cryptoService;
|
private final CryptoService cryptoService;
|
||||||
|
private final Clock clock;
|
||||||
private final ExecutableInput defaultInput;
|
private final ExecutableInput defaultInput;
|
||||||
private final ExecutableCondition defaultCondition;
|
private final ExecutableCondition defaultCondition;
|
||||||
private final List<ActionWrapper> defaultActions;
|
private final List<ActionWrapper> defaultActions;
|
||||||
private final Clock clock;
|
|
||||||
|
|
||||||
public WatchParser(Settings settings, TriggerService triggerService, ActionRegistry actionRegistry, InputRegistry inputRegistry,
|
public WatchParser(Settings settings, TriggerService triggerService, ActionRegistry actionRegistry, InputRegistry inputRegistry,
|
||||||
@Nullable CryptoService cryptoService, Clock clock) {
|
@Nullable CryptoService cryptoService, Clock clock) {
|
||||||
|
|
||||||
super(settings);
|
super(settings);
|
||||||
this.triggerService = triggerService;
|
this.triggerService = triggerService;
|
||||||
this.actionRegistry = actionRegistry;
|
this.actionRegistry = actionRegistry;
|
||||||
this.inputRegistry = inputRegistry;
|
this.inputRegistry = inputRegistry;
|
||||||
this.cryptoService = cryptoService;
|
this.cryptoService = cryptoService;
|
||||||
|
this.clock = clock;
|
||||||
this.defaultInput = new ExecutableNoneInput(logger);
|
this.defaultInput = new ExecutableNoneInput(logger);
|
||||||
this.defaultCondition = InternalAlwaysCondition.INSTANCE;
|
this.defaultCondition = InternalAlwaysCondition.INSTANCE;
|
||||||
this.defaultActions = Collections.emptyList();
|
this.defaultActions = Collections.emptyList();
|
||||||
this.clock = clock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Watch parse(String name, boolean includeStatus, BytesReference source, XContentType xContentType) throws IOException {
|
public Watch parse(String name, boolean includeStatus, BytesReference source, XContentType xContentType) throws IOException {
|
||||||
|
@ -102,23 +100,17 @@ public class WatchParser extends AbstractComponent {
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("parsing watch [{}] ", source.utf8ToString());
|
logger.trace("parsing watch [{}] ", source.utf8ToString());
|
||||||
}
|
}
|
||||||
XContentParser parser = null;
|
|
||||||
try {
|
|
||||||
// EMPTY is safe here because we never use namedObject
|
// EMPTY is safe here because we never use namedObject
|
||||||
parser = new WatcherXContentParser(xContentType.xContent().createParser(NamedXContentRegistry.EMPTY, source),
|
try (WatcherXContentParser parser = new WatcherXContentParser(xContentType.xContent().createParser(NamedXContentRegistry.EMPTY,
|
||||||
new HaltedClock(now), withSecrets ? cryptoService : null);
|
source), now, withSecrets ? cryptoService : null)) {
|
||||||
parser.nextToken();
|
parser.nextToken();
|
||||||
return parse(id, includeStatus, parser);
|
return parse(id, includeStatus, parser);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
throw ioException("could not parse watch [{}]", ioe, id);
|
throw ioException("could not parse watch [{}]", ioe, id);
|
||||||
} finally {
|
|
||||||
if (parser != null) {
|
|
||||||
parser.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Watch parse(String id, boolean includeStatus, XContentParser parser) throws IOException {
|
public Watch parse(String id, boolean includeStatus, WatcherXContentParser parser) throws IOException {
|
||||||
Trigger trigger = null;
|
Trigger trigger = null;
|
||||||
ExecutableInput input = defaultInput;
|
ExecutableInput input = defaultInput;
|
||||||
ExecutableCondition condition = defaultCondition;
|
ExecutableCondition condition = defaultCondition;
|
||||||
|
@ -161,7 +153,7 @@ public class WatchParser extends AbstractComponent {
|
||||||
metatdata = parser.map();
|
metatdata = parser.map();
|
||||||
} else if (WatchField.STATUS.match(currentFieldName)) {
|
} else if (WatchField.STATUS.match(currentFieldName)) {
|
||||||
if (includeStatus) {
|
if (includeStatus) {
|
||||||
status = WatchStatus.parse(id, parser, clock);
|
status = WatchStatus.parse(id, parser);
|
||||||
} else {
|
} else {
|
||||||
parser.skipChildren();
|
parser.skipChildren();
|
||||||
}
|
}
|
||||||
|
@ -185,11 +177,10 @@ public class WatchParser extends AbstractComponent {
|
||||||
} else {
|
} else {
|
||||||
// we need to create the initial statuses for the actions
|
// we need to create the initial statuses for the actions
|
||||||
Map<String, ActionStatus> actionsStatuses = new HashMap<>();
|
Map<String, ActionStatus> actionsStatuses = new HashMap<>();
|
||||||
DateTime now = new DateTime(WatcherXContentParser.clock(parser).millis(), UTC);
|
|
||||||
for (ActionWrapper action : actions) {
|
for (ActionWrapper action : actions) {
|
||||||
actionsStatuses.put(action.id(), new ActionStatus(now));
|
actionsStatuses.put(action.id(), new ActionStatus(parser.getParseDateTime()));
|
||||||
}
|
}
|
||||||
status = new WatchStatus(now, unmodifiableMap(actionsStatuses));
|
status = new WatchStatus(parser.getParseDateTime(), unmodifiableMap(actionsStatuses));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Watch(id, trigger, input, condition, transform, throttlePeriod, actions, metatdata, status);
|
return new Watch(id, trigger, input, condition, transform, throttlePeriod, actions, metatdata, status);
|
||||||
|
|
|
@ -122,6 +122,8 @@ import org.junit.Before;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -179,9 +181,8 @@ public class WatchTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testParserSelfGenerated() throws Exception {
|
public void testParserSelfGenerated() throws Exception {
|
||||||
DateTime now = new DateTime(UTC);
|
Clock clock = Clock.fixed(Instant.now(), ZoneOffset.UTC);
|
||||||
ClockMock clock = ClockMock.frozen();
|
DateTime now = new DateTime(clock.millis(), UTC);
|
||||||
clock.setTime(now);
|
|
||||||
TransformRegistry transformRegistry = transformRegistry();
|
TransformRegistry transformRegistry = transformRegistry();
|
||||||
boolean includeStatus = randomBoolean();
|
boolean includeStatus = randomBoolean();
|
||||||
Schedule schedule = randomSchedule();
|
Schedule schedule = randomSchedule();
|
||||||
|
@ -207,7 +208,7 @@ public class WatchTests extends ESTestCase {
|
||||||
for (ActionWrapper action : actions) {
|
for (ActionWrapper action : actions) {
|
||||||
actionsStatuses.put(action.id(), new ActionStatus(now));
|
actionsStatuses.put(action.id(), new ActionStatus(now));
|
||||||
}
|
}
|
||||||
WatchStatus watchStatus = new WatchStatus(new DateTime(clock.millis()), unmodifiableMap(actionsStatuses));
|
WatchStatus watchStatus = new WatchStatus(now, unmodifiableMap(actionsStatuses));
|
||||||
|
|
||||||
TimeValue throttlePeriod = randomBoolean() ? null : TimeValue.timeValueSeconds(randomIntBetween(5, 10000));
|
TimeValue throttlePeriod = randomBoolean() ? null : TimeValue.timeValueSeconds(randomIntBetween(5, 10000));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue