Watcher: Replace _status field with status (elastic/x-pack-elasticsearch#1285)
As fields with underscores will be disallowed in master, and we have to prepare the upgrade, this commit renames the _status field to status. When the 5.x upgrade logic is in place in the 5.x we can remove all the old style _status handling from the master branch. Note: All the BWC compatibility tests, that load 5.x indices are now faking a finished upgrade by adding the `status` field to the mapping of the watches index. Original commit: elastic/x-pack-elasticsearch@9d5cc9aaec
This commit is contained in:
parent
8633fd1f07
commit
4078b2f1b2
|
@ -3,7 +3,7 @@
|
|||
|
||||
<<actions-ack-throttle, Acknowledging>> a watch enables you to manually throttle
|
||||
execution of the watch's actions. An action's _acknowledgement state_ is stored
|
||||
in the `_status.actions.<id>.ack.state` structure.
|
||||
in the `status.actions.<id>.ack.state` structure.
|
||||
|
||||
To demonstrate let's create a new watch:
|
||||
|
||||
|
@ -58,7 +58,7 @@ The action state of a newly-created watch is `awaits_successful_execution`:
|
|||
{
|
||||
"found": true,
|
||||
"_id": "my_watch",
|
||||
"_status": {
|
||||
"status": {
|
||||
"version": 1,
|
||||
"actions": {
|
||||
"test_index": {
|
||||
|
@ -73,9 +73,9 @@ The action state of a newly-created watch is `awaits_successful_execution`:
|
|||
"watch": ...
|
||||
}
|
||||
--------------------------------------------------
|
||||
// TESTRESPONSE[s/"state": \.\.\./"state": "$body._status.state"/]
|
||||
// TESTRESPONSE[s/"state": \.\.\./"state": "$body.status.state"/]
|
||||
// TESTRESPONSE[s/"watch": \.\.\./"watch": "$body.watch"/]
|
||||
// TESTRESPONSE[s/"timestamp": "2015-05-26T18:04:27.723Z"/"timestamp": "$body._status.actions.test_index.ack.timestamp"/]
|
||||
// TESTRESPONSE[s/"timestamp": "2015-05-26T18:04:27.723Z"/"timestamp": "$body.status.actions.test_index.ack.timestamp"/]
|
||||
|
||||
When the watch executes and the condition matches, the value of the `ack.state`
|
||||
changes to `ackable`. Let's force execution of the watch and fetch it again to
|
||||
|
@ -95,7 +95,7 @@ and the action is now in `ackable` state:
|
|||
{
|
||||
"found": true,
|
||||
"_id": "my_watch",
|
||||
"_status": {
|
||||
"status": {
|
||||
"version": 1,
|
||||
"actions": {
|
||||
"test_index": {
|
||||
|
@ -110,9 +110,9 @@ and the action is now in `ackable` state:
|
|||
"watch": ...
|
||||
}
|
||||
--------------------------------------------------
|
||||
// TESTRESPONSE[s/"state": \.\.\./"state": "$body._status.state"/]
|
||||
// TESTRESPONSE[s/"state": \.\.\./"state": "$body.status.state"/]
|
||||
// TESTRESPONSE[s/"watch": \.\.\./"watch": "$body.watch"/]
|
||||
// TESTRESPONSE[s/"timestamp": "2015-05-26T18:04:27.723Z"/"timestamp": "$body._status.actions.test_index.ack.timestamp"/]
|
||||
// TESTRESPONSE[s/"timestamp": "2015-05-26T18:04:27.723Z"/"timestamp": "$body.status.actions.test_index.ack.timestamp"/]
|
||||
|
||||
Now we can acknowledge it:
|
||||
|
||||
|
@ -128,7 +128,7 @@ GET _xpack/watcher/watch/my_watch
|
|||
{
|
||||
"found": true,
|
||||
"_id": "my_watch",
|
||||
"_status": {
|
||||
"status": {
|
||||
"version": 1,
|
||||
"actions": {
|
||||
"test_index": {
|
||||
|
@ -143,9 +143,9 @@ GET _xpack/watcher/watch/my_watch
|
|||
"watch": ...
|
||||
}
|
||||
--------------------------------------------------
|
||||
// TESTRESPONSE[s/"state": \.\.\./"state": "$body._status.state"/]
|
||||
// TESTRESPONSE[s/"state": \.\.\./"state": "$body.status.state"/]
|
||||
// TESTRESPONSE[s/"watch": \.\.\./"watch": "$body.watch"/]
|
||||
// TESTRESPONSE[s/"timestamp": "2015-05-26T18:04:27.723Z"/"timestamp": "$body._status.actions.test_index.ack.timestamp"/]
|
||||
// TESTRESPONSE[s/"timestamp": "2015-05-26T18:04:27.723Z"/"timestamp": "$body.status.actions.test_index.ack.timestamp"/]
|
||||
|
||||
Acknowledging an action throttles further executions of that action until its
|
||||
`ack.state` is reset to `awaits_successful_execution`. This happens when the
|
||||
|
@ -195,7 +195,7 @@ The response format looks like:
|
|||
[source,js]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"_status": {
|
||||
"status": {
|
||||
"last_checked": "2015-05-26T18:21:08.630Z",
|
||||
"last_met_condition": "2015-05-26T18:21:08.630Z",
|
||||
"actions": {
|
||||
|
|
|
@ -19,7 +19,7 @@ GET _xpack/watcher/watch/my_watch
|
|||
{
|
||||
"found": true,
|
||||
"_id": "my_watch",
|
||||
"_status": {
|
||||
"status": {
|
||||
"state" : {
|
||||
"active" : false,
|
||||
"timestamp" : "2015-08-20T12:21:32.734Z"
|
||||
|
@ -30,10 +30,10 @@ GET _xpack/watcher/watch/my_watch
|
|||
"watch": ...
|
||||
}
|
||||
--------------------------------------------------
|
||||
// TESTRESPONSE[s/2015-08-20T12:21:32.734Z/$body._status.state.timestamp/]
|
||||
// TESTRESPONSE[s/"actions": \.\.\./"actions": "$body._status.actions"/]
|
||||
// TESTRESPONSE[s/2015-08-20T12:21:32.734Z/$body.status.state.timestamp/]
|
||||
// TESTRESPONSE[s/"actions": \.\.\./"actions": "$body.status.actions"/]
|
||||
// TESTRESPONSE[s/"watch": \.\.\./"watch": "$body.watch"/]
|
||||
// TESTRESPONSE[s/"version": 1/"version": $body._status.version/]
|
||||
// TESTRESPONSE[s/"version": 1/"version": $body.status.version/]
|
||||
|
||||
You can activate the watch by executing the following API call:
|
||||
|
||||
|
@ -49,7 +49,7 @@ The new state of the watch is returned as part of its overall status:
|
|||
[source,js]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"_status": {
|
||||
"status": {
|
||||
"state" : {
|
||||
"active" : true,
|
||||
"timestamp" : "2015-09-04T08:39:46.816Z"
|
||||
|
@ -59,6 +59,6 @@ The new state of the watch is returned as part of its overall status:
|
|||
}
|
||||
}
|
||||
--------------------------------------------------
|
||||
// TESTRESPONSE[s/2015-09-04T08:39:46.816Z/$body._status.state.timestamp/]
|
||||
// TESTRESPONSE[s/"actions": \.\.\./"actions": "$body._status.actions"/]
|
||||
// TESTRESPONSE[s/"version": 1/"version": $body._status.version/]
|
||||
// TESTRESPONSE[s/2015-09-04T08:39:46.816Z/$body.status.state.timestamp/]
|
||||
// TESTRESPONSE[s/"actions": \.\.\./"actions": "$body.status.actions"/]
|
||||
// TESTRESPONSE[s/"version": 1/"version": $body.status.version/]
|
||||
|
|
|
@ -19,7 +19,7 @@ GET _xpack/watcher/watch/my_watch
|
|||
{
|
||||
"found": true,
|
||||
"_id": "my_watch",
|
||||
"_status": {
|
||||
"status": {
|
||||
"state" : {
|
||||
"active" : true,
|
||||
"timestamp" : "2015-08-20T12:21:32.734Z"
|
||||
|
@ -30,10 +30,10 @@ GET _xpack/watcher/watch/my_watch
|
|||
"watch": ...
|
||||
}
|
||||
--------------------------------------------------
|
||||
// TESTRESPONSE[s/2015-08-20T12:21:32.734Z/$body._status.state.timestamp/]
|
||||
// TESTRESPONSE[s/"actions": \.\.\./"actions": "$body._status.actions"/]
|
||||
// TESTRESPONSE[s/2015-08-20T12:21:32.734Z/$body.status.state.timestamp/]
|
||||
// TESTRESPONSE[s/"actions": \.\.\./"actions": "$body.status.actions"/]
|
||||
// TESTRESPONSE[s/"watch": \.\.\./"watch": "$body.watch"/]
|
||||
// TESTRESPONSE[s/"version": 1/"version": $body._status.version/]
|
||||
// TESTRESPONSE[s/"version": 1/"version": $body.status.version/]
|
||||
|
||||
You can deactivate the watch by executing the following API call:
|
||||
|
||||
|
@ -49,7 +49,7 @@ The new state of the watch is returned as part of its overall status:
|
|||
[source,js]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"_status": {
|
||||
"status": {
|
||||
"state" : {
|
||||
"active" : false,
|
||||
"timestamp" : "2015-09-04T08:39:46.816Z"
|
||||
|
@ -59,6 +59,6 @@ The new state of the watch is returned as part of its overall status:
|
|||
}
|
||||
}
|
||||
--------------------------------------------------
|
||||
// TESTRESPONSE[s/2015-09-04T08:39:46.816Z/$body._status.state.timestamp/]
|
||||
// TESTRESPONSE[s/"actions": \.\.\./"actions": "$body._status.actions"/]
|
||||
// TESTRESPONSE[s/"version": 1/"version": $body._status.version/]
|
||||
// TESTRESPONSE[s/2015-09-04T08:39:46.816Z/$body.status.state.timestamp/]
|
||||
// TESTRESPONSE[s/"actions": \.\.\./"actions": "$body.status.actions"/]
|
||||
// TESTRESPONSE[s/"version": 1/"version": $body.status.version/]
|
||||
|
|
|
@ -104,7 +104,7 @@ This is an example of the output:
|
|||
}
|
||||
},
|
||||
"state": "executed",
|
||||
"_status": {
|
||||
"status": {
|
||||
"version": 1,
|
||||
"state": {
|
||||
"active": true,
|
||||
|
@ -179,10 +179,10 @@ This is an example of the output:
|
|||
// TESTRESPONSE[s/"triggered_time": "2015-06-02T23:17:55.124Z"/"triggered_time": "$body.watch_record.trigger_event.triggered_time"/]
|
||||
// TESTRESPONSE[s/"scheduled_time": "2015-06-02T23:17:55.124Z"/"scheduled_time": "$body.watch_record.trigger_event.manual.schedule.scheduled_time"/]
|
||||
// TESTRESPONSE[s/"execution_time": "2015-06-02T23:17:55.124Z"/"execution_time": "$body.watch_record.result.execution_time"/]
|
||||
// TESTRESPONSE[s/"timestamp": "2015-06-02T23:17:55.111Z"/"timestamp": "$body.watch_record._status.state.timestamp"/]
|
||||
// TESTRESPONSE[s/"timestamp": "2015-06-02T23:17:55.124Z"/"timestamp": "$body.watch_record._status.actions.test_index.ack.timestamp"/]
|
||||
// TESTRESPONSE[s/"last_checked": "2015-06-02T23:17:55.124Z"/"last_checked": "$body.watch_record._status.last_checked"/]
|
||||
// TESTRESPONSE[s/"last_met_condition": "2015-06-02T23:17:55.124Z"/"last_met_condition": "$body.watch_record._status.last_met_condition"/]
|
||||
// TESTRESPONSE[s/"timestamp": "2015-06-02T23:17:55.111Z"/"timestamp": "$body.watch_record.status.state.timestamp"/]
|
||||
// TESTRESPONSE[s/"timestamp": "2015-06-02T23:17:55.124Z"/"timestamp": "$body.watch_record.status.actions.test_index.ack.timestamp"/]
|
||||
// TESTRESPONSE[s/"last_checked": "2015-06-02T23:17:55.124Z"/"last_checked": "$body.watch_record.status.last_checked"/]
|
||||
// TESTRESPONSE[s/"last_met_condition": "2015-06-02T23:17:55.124Z"/"last_met_condition": "$body.watch_record.status.last_met_condition"/]
|
||||
// TESTRESPONSE[s/"execution_duration": 12608/"execution_duration": "$body.watch_record.result.execution_duration"/]
|
||||
// TESTRESPONSE[s/"id": "AVSHKzPa9zx62AzUzFXY"/"id": "$body.watch_record.result.actions.0.index.response.id"/]
|
||||
// TESTRESPONSE[s/"node": "my_node"/"node": "$body.watch_record.node"/]
|
||||
|
|
|
@ -19,7 +19,7 @@ Response:
|
|||
{
|
||||
"found": true,
|
||||
"_id": "my_watch",
|
||||
"_status": { <1>
|
||||
"status": { <1>
|
||||
"version": 1,
|
||||
"state": {
|
||||
"active": true,
|
||||
|
@ -63,5 +63,5 @@ Response:
|
|||
}
|
||||
}
|
||||
--------------------------------------------------
|
||||
// TESTRESPONSE[s/"timestamp": "2015-05-26T18:21:08.630Z"/"timestamp": "$body._status.state.timestamp"/]
|
||||
// TESTRESPONSE[s/"timestamp": "2015-05-26T18:21:08.630Z"/"timestamp": "$body.status.state.timestamp"/]
|
||||
<1> The current status of the watch
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<<actions-ack-throttle, Acknowledging>> a watch enables you to manually throttle
|
||||
execution of the watch actions. The action's _acknowledgement state_ is stored in
|
||||
the `_status.actions.<id>.ack.state` structure.
|
||||
the `status.actions.<id>.ack.state` structure.
|
||||
|
||||
The current status of the watch and the state of its actions are returned as part
|
||||
of the <<api-java-get-watch, Get Watch API>> response:
|
||||
|
|
|
@ -137,7 +137,7 @@ public abstract class WatchRecord implements ToXContentObject {
|
|||
builder.field(Field.STATE.getPreferredName(), state.id());
|
||||
|
||||
if (watch != null && watch.status() != null) {
|
||||
builder.field("_status", watch.status(), params);
|
||||
builder.field(Field.STATUS.getPreferredName(), watch.status(), params);
|
||||
}
|
||||
|
||||
builder.field(Field.TRIGGER_EVENT.getPreferredName());
|
||||
|
@ -195,7 +195,7 @@ public abstract class WatchRecord implements ToXContentObject {
|
|||
ParseField TRIGGER_EVENT = new ParseField("trigger_event");
|
||||
ParseField MESSAGES = new ParseField("messages");
|
||||
ParseField STATE = new ParseField("state");
|
||||
ParseField STATUS = new ParseField("_status");
|
||||
ParseField STATUS = new ParseField("status");
|
||||
ParseField VARS = new ParseField("vars");
|
||||
ParseField METADATA = new ParseField("metadata");
|
||||
ParseField EXECUTION_RESULT = new ParseField("result");
|
||||
|
|
|
@ -45,7 +45,7 @@ public class RestGetWatchAction extends WatcherRestHandler {
|
|||
.field("_id", response.getId());
|
||||
if (response.isFound()) {
|
||||
ToXContent.MapParams xContentParams = new ToXContent.MapParams(request.params());
|
||||
builder.field("_status", response.getStatus(), xContentParams);
|
||||
builder.field("status", response.getStatus(), xContentParams);
|
||||
builder.field("watch", response.getSource(), xContentParams);
|
||||
}
|
||||
builder.endObject();
|
||||
|
|
|
@ -37,7 +37,7 @@ import static java.util.Collections.unmodifiableMap;
|
|||
public class WatcherIndexTemplateRegistry extends AbstractComponent implements ClusterStateListener {
|
||||
|
||||
private static final String FORBIDDEN_INDEX_SETTING = "index.mapper.dynamic";
|
||||
public static final String INDEX_TEMPLATE_VERSION = "4";
|
||||
public static final String INDEX_TEMPLATE_VERSION = "5";
|
||||
|
||||
public static final String HISTORY_TEMPLATE_NAME = "watch_history_" + INDEX_TEMPLATE_VERSION;
|
||||
public static final String TRIGGERED_TEMPLATE_NAME = "triggered_watches";
|
||||
|
|
|
@ -303,7 +303,7 @@ public class Watch implements ToXContentObject {
|
|||
actions = actionRegistry.parseActions(id, parser);
|
||||
} else if (Field.METADATA.match(currentFieldName)) {
|
||||
metatdata = parser.map();
|
||||
} else if (Field.STATUS.match(currentFieldName)) {
|
||||
} else if (Field.STATUS.match(currentFieldName) || Field.STATUS_V5.match(currentFieldName)) {
|
||||
if (includeStatus) {
|
||||
status = WatchStatus.parse(id, parser, clock);
|
||||
} else {
|
||||
|
@ -349,7 +349,8 @@ public class Watch implements ToXContentObject {
|
|||
ParseField THROTTLE_PERIOD = new ParseField("throttle_period_in_millis");
|
||||
ParseField THROTTLE_PERIOD_HUMAN = new ParseField("throttle_period");
|
||||
ParseField METADATA = new ParseField("metadata");
|
||||
ParseField STATUS = new ParseField("_status");
|
||||
ParseField STATUS = new ParseField("status");
|
||||
ParseField STATUS_V5 = new ParseField("_status");
|
||||
}
|
||||
|
||||
private static final Pattern NO_WS_PATTERN = Pattern.compile("\\S+");
|
||||
|
|
|
@ -103,6 +103,11 @@
|
|||
"enabled" : false,
|
||||
"dynamic" : true
|
||||
},
|
||||
"status": {
|
||||
"type": "object",
|
||||
"enabled" : false,
|
||||
"dynamic" : true
|
||||
},
|
||||
"messages": {
|
||||
"type": "text"
|
||||
},
|
||||
|
|
|
@ -15,6 +15,11 @@
|
|||
"enabled" : false,
|
||||
"dynamic" : true
|
||||
},
|
||||
"status": {
|
||||
"type": "object",
|
||||
"enabled" : false,
|
||||
"dynamic" : true
|
||||
},
|
||||
"trigger" : {
|
||||
"type": "object",
|
||||
"enabled" : false,
|
||||
|
|
|
@ -21,12 +21,15 @@ import org.elasticsearch.xpack.watcher.transport.actions.stats.WatcherStatsRespo
|
|||
import org.elasticsearch.xpack.watcher.trigger.schedule.IntervalSchedule;
|
||||
import org.elasticsearch.xpack.watcher.trigger.schedule.IntervalSchedule.Interval;
|
||||
import org.elasticsearch.xpack.watcher.trigger.schedule.ScheduleTrigger;
|
||||
import org.elasticsearch.xpack.watcher.watch.Watch;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds;
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.hamcrest.Matchers.everyItem;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.hasEntry;
|
||||
|
@ -57,6 +60,17 @@ public class OldWatcherIndicesBackwardsCompatibilityTests extends AbstractOldXPa
|
|||
.stream().map(WatcherStatsResponse.Node::getWatcherState).collect(Collectors.toList());
|
||||
assertThat(states, everyItem(is(WatcherState.STARTED)));
|
||||
});
|
||||
|
||||
// in order to go from 5.x to master, we assume someone executed the upgrade API, which will install the new index templates
|
||||
// in this test we just do this manually, by adding the _status field to the mapping
|
||||
// this can be removed once the API supports regular upgrade from 5.x to 6.x
|
||||
assertAcked(client().admin().indices().preparePutMapping(Watch.INDEX).setType(Watch.DOC_TYPE)
|
||||
.setSource(jsonBuilder().startObject().startObject("properties").startObject("status")
|
||||
.field("type", "object")
|
||||
.field("enabled", false)
|
||||
.field("dynamic", true).endObject().endObject().endObject())
|
||||
.get());
|
||||
|
||||
try {
|
||||
assertWatchIndexContentsWork(version);
|
||||
assertBasicWatchInteractions();
|
||||
|
|
|
@ -147,7 +147,7 @@ public class ManualExecutionTests extends AbstractWatcherIntegrationTestCase {
|
|||
is(ActionStatus.AckStatus.State.AWAITS_SUCCESSFUL_EXECUTION));
|
||||
}
|
||||
} else {
|
||||
String ackState = executeWatchResponse.getRecordSource().getValue("_status.actions.log.ack.state");
|
||||
String ackState = executeWatchResponse.getRecordSource().getValue("status.actions.log.ack.state");
|
||||
if (ignoreCondition || conditionAlwaysTrue) {
|
||||
assertThat(ackState, is(ActionStatus.AckStatus.State.ACKABLE.toString().toLowerCase(Locale.ROOT)));
|
||||
} else {
|
||||
|
|
|
@ -176,32 +176,32 @@ public class HistoryIntegrationTests extends AbstractWatcherIntegrationTestCase
|
|||
|
||||
XContentSource source = new XContentSource(hit.getSourceRef(), XContentType.JSON);
|
||||
|
||||
Boolean active = source.getValue("_status.state.active");
|
||||
Boolean active = source.getValue("status.state.active");
|
||||
assertThat(active, is(status.state().isActive()));
|
||||
|
||||
String timestamp = source.getValue("_status.state.timestamp");
|
||||
String timestamp = source.getValue("status.state.timestamp");
|
||||
assertThat(timestamp, is(status.state().getTimestamp().toString()));
|
||||
|
||||
String lastChecked = source.getValue("_status.last_checked");
|
||||
String lastChecked = source.getValue("status.last_checked");
|
||||
assertThat(lastChecked, is(status.lastChecked().toString()));
|
||||
|
||||
Integer version = source.getValue("_status.version");
|
||||
Integer version = source.getValue("status.version");
|
||||
int expectedVersion = (int) (status.version() - 1);
|
||||
assertThat(version, is(expectedVersion));
|
||||
|
||||
ActionStatus actionStatus = status.actionStatus("_logger");
|
||||
String ackStatusState = source.getValue("_status.actions._logger.ack.state").toString().toUpperCase(Locale.ROOT);
|
||||
String ackStatusState = source.getValue("status.actions._logger.ack.state").toString().toUpperCase(Locale.ROOT);
|
||||
assertThat(ackStatusState, is(actionStatus.ackStatus().state().toString()));
|
||||
|
||||
Boolean lastExecutionSuccesful = source.getValue("_status.actions._logger.last_execution.successful");
|
||||
Boolean lastExecutionSuccesful = source.getValue("status.actions._logger.last_execution.successful");
|
||||
assertThat(lastExecutionSuccesful, is(actionStatus.lastExecution().successful()));
|
||||
|
||||
// also ensure that the _status field is disabled in the watch history
|
||||
// also ensure that the status field is disabled in the watch history
|
||||
GetMappingsResponse response = client().admin().indices().prepareGetMappings(".watcher-history*").addTypes("watch_record").get();
|
||||
byte[] bytes = response.getMappings().values().iterator().next().value.get("watch_record").source().uncompressed();
|
||||
XContentSource mappingSource = new XContentSource(new BytesArray(bytes), XContentType.JSON);
|
||||
assertThat(mappingSource.getValue("watch_record.properties._status.enabled"), is(false));
|
||||
assertThat(mappingSource.getValue("watch_record.properties._status.properties.status"), is(nullValue()));
|
||||
assertThat(mappingSource.getValue("watch_record.properties._status.properties.status.properties.active"), is(nullValue()));
|
||||
assertThat(mappingSource.getValue("watch_record.properties.status.enabled"), is(false));
|
||||
assertThat(mappingSource.getValue("watch_record.properties.status.properties.status"), is(nullValue()));
|
||||
assertThat(mappingSource.getValue("watch_record.properties.status.properties.status.properties.active"), is(nullValue()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,10 +147,10 @@ public class ActivateWatchTests extends AbstractWatcherIntegrationTestCase {
|
|||
"transform.**",
|
||||
"actions.**",
|
||||
"metadata.**",
|
||||
"_status.version",
|
||||
"_status.last_checked",
|
||||
"_status.last_met_condition",
|
||||
"_status.actions.**");
|
||||
"status.version",
|
||||
"status.last_checked",
|
||||
"status.last_met_condition",
|
||||
"status.actions.**");
|
||||
|
||||
XContentBuilder builder = new XContentBuilder(XContentType.JSON.xContent(), new BytesStreamOutput(), filters);
|
||||
source.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
||||
|
|
|
@ -81,7 +81,7 @@ public class ExecuteWatchTests extends AbstractWatcherIntegrationTestCase {
|
|||
assertValue(record, "result.actions.0.type", is("logging"));
|
||||
assertValue(record, "result.actions.0.status", is("success"));
|
||||
assertValue(record, "result.actions.0.logging.logged_text", is("_text"));
|
||||
assertValue(record, "_status.actions.log.ack.state", is("ackable"));
|
||||
assertValue(record, "status.actions.log.ack.state", is("ackable"));
|
||||
}
|
||||
|
||||
public void testExecuteCustomTriggerData() throws Exception {
|
||||
|
|
|
@ -48,7 +48,7 @@ public class WatchStatusIntegrationTests extends AbstractWatcherIntegrationTestC
|
|||
GetResponse getResponse = client().prepareGet(".watches", "watch", "_name").get();
|
||||
getResponse.getSource();
|
||||
XContentSource source = new XContentSource(getResponse.getSourceAsBytesRef(), XContentType.JSON);
|
||||
String lastChecked = source.getValue("_status.last_checked");
|
||||
String lastChecked = source.getValue("status.last_checked");
|
||||
|
||||
assertThat(lastChecked, is(notNullValue()));
|
||||
assertThat(getWatchResponse.getStatus().lastChecked().toString(), is(lastChecked));
|
||||
|
|
|
@ -15,7 +15,7 @@ import org.elasticsearch.common.settings.Settings;
|
|||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.index.query.MatchAllQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
|
@ -112,6 +112,7 @@ import org.joda.time.DateTime;
|
|||
import org.joda.time.DateTimeZone;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Clock;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -127,6 +128,7 @@ import static java.util.Collections.singleton;
|
|||
import static java.util.Collections.singletonMap;
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds;
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource;
|
||||
import static org.elasticsearch.xpack.watcher.input.InputBuilders.searchInput;
|
||||
import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.templateRequest;
|
||||
|
@ -201,7 +203,7 @@ public class WatchTests extends ESTestCase {
|
|||
|
||||
Watch watch = new Watch("_name", trigger, input, condition, transform, throttlePeriod, actions, metadata, watchStatus);
|
||||
|
||||
BytesReference bytes = XContentFactory.jsonBuilder().value(watch).bytes();
|
||||
BytesReference bytes = jsonBuilder().value(watch).bytes();
|
||||
logger.info("{}", bytes.utf8ToString());
|
||||
Watch.Parser watchParser = new Watch.Parser(settings, triggerService, actionRegistry, inputRegistry, null, clock);
|
||||
|
||||
|
@ -220,6 +222,49 @@ public class WatchTests extends ESTestCase {
|
|||
assertThat(parsedWatch.actions(), equalTo(actions));
|
||||
}
|
||||
|
||||
public void testThatBothStatusFieldsCanBeRead() throws Exception {
|
||||
InputRegistry inputRegistry = mock(InputRegistry.class);
|
||||
ActionRegistry actionRegistry = mock(ActionRegistry.class);
|
||||
// a fake trigger service that advances past the trigger end object, which cannot be done with mocking
|
||||
TriggerService triggerService = new TriggerService(Settings.EMPTY, Collections.emptySet()) {
|
||||
@Override
|
||||
public Trigger parseTrigger(String jobName, XContentParser parser) throws IOException {
|
||||
XContentParser.Token token;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
}
|
||||
|
||||
return new ScheduleTrigger(randomSchedule());
|
||||
}
|
||||
};
|
||||
|
||||
DateTime now = new DateTime(UTC);
|
||||
ClockMock clock = ClockMock.frozen();
|
||||
clock.setTime(now);
|
||||
|
||||
List<ActionWrapper> actions = randomActions();
|
||||
Map<String, ActionStatus> actionsStatuses = new HashMap<>();
|
||||
for (ActionWrapper action : actions) {
|
||||
actionsStatuses.put(action.id(), new ActionStatus(now));
|
||||
}
|
||||
WatchStatus watchStatus = new WatchStatus(new DateTime(clock.millis()), unmodifiableMap(actionsStatuses));
|
||||
|
||||
Watch.Parser watchParser = new Watch.Parser(settings, triggerService, actionRegistry, inputRegistry, null, clock);
|
||||
XContentBuilder builder = jsonBuilder().startObject()
|
||||
.startObject("trigger").endObject();
|
||||
if (randomBoolean()) {
|
||||
builder.field("_status", watchStatus);
|
||||
} else {
|
||||
builder.field("status", watchStatus);
|
||||
}
|
||||
|
||||
builder.endObject();
|
||||
Watch watch = watchParser.parse("foo", true, builder.bytes(), XContentType.JSON);
|
||||
assertThat(watch.status().state().getTimestamp().getMillis(), is(clock.millis()));
|
||||
for (ActionWrapper action : actions) {
|
||||
assertThat(watch.status().actionStatus(action.id()), is(actionsStatuses.get(action.id())));
|
||||
}
|
||||
}
|
||||
|
||||
public void testParserBadActions() throws Exception {
|
||||
ClockMock clock = ClockMock.frozen();
|
||||
ScheduleRegistry scheduleRegistry = registry(randomSchedule());
|
||||
|
@ -235,7 +280,7 @@ public class WatchTests extends ESTestCase {
|
|||
ActionRegistry actionRegistry = registry(actions,conditionRegistry, transformRegistry);
|
||||
|
||||
|
||||
XContentBuilder jsonBuilder = XContentFactory.jsonBuilder()
|
||||
XContentBuilder jsonBuilder = jsonBuilder()
|
||||
.startObject()
|
||||
.startArray("actions").endArray()
|
||||
.endObject();
|
||||
|
@ -259,7 +304,7 @@ public class WatchTests extends ESTestCase {
|
|||
TransformRegistry transformRegistry = transformRegistry();
|
||||
ActionRegistry actionRegistry = registry(Collections.emptyList(), conditionRegistry, transformRegistry);
|
||||
|
||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||
XContentBuilder builder = jsonBuilder();
|
||||
builder.startObject();
|
||||
builder.startObject(Watch.Field.TRIGGER.getPreferredName())
|
||||
.field(ScheduleTrigger.TYPE, schedule(schedule).build())
|
||||
|
@ -290,7 +335,7 @@ public class WatchTests extends ESTestCase {
|
|||
|
||||
WatcherSearchTemplateService searchTemplateService = new WatcherSearchTemplateService(settings, scriptService, xContentRegistry());
|
||||
|
||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||
XContentBuilder builder = jsonBuilder();
|
||||
builder.startObject();
|
||||
|
||||
builder.startObject("trigger");
|
||||
|
|
|
@ -43,14 +43,14 @@
|
|||
xpack.watcher.ack_watch:
|
||||
watch_id: "my_watch"
|
||||
|
||||
- match: { "_status.actions.test_index.ack.state" : "awaits_successful_execution" }
|
||||
- match: { "status.actions.test_index.ack.state" : "awaits_successful_execution" }
|
||||
|
||||
- do:
|
||||
search:
|
||||
index: .watches
|
||||
body: { "query": { "term": { "_id": "my_watch" } } }
|
||||
- match: { hits.total: 1 }
|
||||
- match: { hits.hits.0._source._status.actions.test_index.ack.state: "awaits_successful_execution" }
|
||||
- match: { hits.hits.0._source.status.actions.test_index.ack.state: "awaits_successful_execution" }
|
||||
|
||||
- do:
|
||||
xpack.watcher.delete_watch:
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
watch_id: "my_watch"
|
||||
action_id: "test_index"
|
||||
|
||||
- match: { "_status.actions.test_index.ack.state" : "awaits_successful_execution" }
|
||||
- match: { "status.actions.test_index.ack.state" : "awaits_successful_execution" }
|
||||
|
||||
- do:
|
||||
xpack.watcher.delete_watch:
|
||||
|
|
|
@ -53,17 +53,17 @@ teardown:
|
|||
{
|
||||
"record_execution" : true
|
||||
}
|
||||
- match: { watch_record._status.actions.indexme.ack.state: "ackable" }
|
||||
- match: { watch_record.status.actions.indexme.ack.state: "ackable" }
|
||||
|
||||
- do:
|
||||
xpack.watcher.ack_watch:
|
||||
watch_id: "my_watch"
|
||||
- match: { "_status.actions.indexme.ack.state" : "acked" }
|
||||
- match: { "status.actions.indexme.ack.state" : "acked" }
|
||||
|
||||
- do:
|
||||
xpack.watcher.get_watch:
|
||||
id: "my_watch"
|
||||
- match: { "_status.actions.indexme.ack.state" : "acked" }
|
||||
- match: { "status.actions.indexme.ack.state" : "acked" }
|
||||
|
||||
# having a false result will reset the ack state
|
||||
- do:
|
||||
|
@ -79,12 +79,12 @@ teardown:
|
|||
"indexme" : "force_execute"
|
||||
}
|
||||
}
|
||||
- match: { watch_record._status.actions.indexme.ack.state: "awaits_successful_execution" }
|
||||
- match: { watch_record.status.actions.indexme.ack.state: "awaits_successful_execution" }
|
||||
|
||||
- do:
|
||||
xpack.watcher.get_watch:
|
||||
id: "my_watch"
|
||||
- match: { "_status.actions.indexme.ack.state" : "awaits_successful_execution" }
|
||||
- match: { "status.actions.indexme.ack.state" : "awaits_successful_execution" }
|
||||
|
||||
- do:
|
||||
xpack.watcher.execute_watch:
|
||||
|
@ -96,10 +96,10 @@ teardown:
|
|||
"indexme" : "force_execute"
|
||||
}
|
||||
}
|
||||
- match: { watch_record._status.actions.indexme.ack.state: "ackable" }
|
||||
- match: { watch_record.status.actions.indexme.ack.state: "ackable" }
|
||||
|
||||
- do:
|
||||
xpack.watcher.get_watch:
|
||||
id: "my_watch"
|
||||
- match: { "_status.actions.indexme.ack.state" : "ackable" }
|
||||
- match: { "status.actions.indexme.ack.state" : "ackable" }
|
||||
|
||||
|
|
|
@ -41,40 +41,40 @@
|
|||
|
||||
- match: { found : true}
|
||||
- match: { _id: "my_watch" }
|
||||
- match: { _status.state.active: true }
|
||||
- match: { status.state.active: true }
|
||||
|
||||
- do:
|
||||
xpack.watcher.deactivate_watch:
|
||||
watch_id: "my_watch"
|
||||
|
||||
- match: { _status.state.active : false }
|
||||
- match: { status.state.active : false }
|
||||
|
||||
- do:
|
||||
search:
|
||||
index: .watches
|
||||
body: { "query": { "term": { "_id": "my_watch" } } }
|
||||
- match: { hits.total: 1 }
|
||||
- match: { hits.hits.0._source._status.state.active: false }
|
||||
- match: { hits.hits.0._source.status.state.active: false }
|
||||
|
||||
- do:
|
||||
xpack.watcher.get_watch:
|
||||
id: "my_watch"
|
||||
- match: { found : true}
|
||||
- match: { _id: "my_watch" }
|
||||
- match: { _status.state.active: false }
|
||||
- match: { status.state.active: false }
|
||||
|
||||
- do:
|
||||
xpack.watcher.activate_watch:
|
||||
watch_id: "my_watch"
|
||||
|
||||
- match: { _status.state.active : true }
|
||||
- match: { status.state.active : true }
|
||||
|
||||
- do:
|
||||
search:
|
||||
index: .watches
|
||||
body: { "query": { "term": { "_id": "my_watch" } } }
|
||||
- match: { hits.total: 1 }
|
||||
- match: { hits.hits.0._source._status.state.active: true }
|
||||
- match: { hits.hits.0._source.status.state.active: true }
|
||||
|
||||
- do:
|
||||
xpack.watcher.get_watch:
|
||||
|
@ -82,7 +82,7 @@
|
|||
|
||||
- match: { found : true}
|
||||
- match: { _id: "my_watch" }
|
||||
- match: { _status.state.active: true }
|
||||
- match: { status.state.active: true }
|
||||
|
||||
- do:
|
||||
xpack.watcher.delete_watch:
|
||||
|
|
|
@ -58,9 +58,9 @@ teardown:
|
|||
- match: { watch_record.trigger_event.triggered_time: "2012-12-12T12:12:12.120Z" }
|
||||
- match: { watch_record.trigger_event.manual.schedule.scheduled_time: "2000-12-12T12:12:12.120Z" }
|
||||
- match: { watch_record.state: "executed" }
|
||||
- match: { watch_record._status.state.active: true }
|
||||
- match: { watch_record.status.state.active: true }
|
||||
- is_true: watch_record.node
|
||||
- match: { watch_record._status.actions.indexme.ack.state: "ackable" }
|
||||
- match: { watch_record.status.actions.indexme.ack.state: "ackable" }
|
||||
|
||||
---
|
||||
"Test execute watch API with user supplied watch":
|
||||
|
@ -96,8 +96,8 @@ teardown:
|
|||
- match: { watch_record.watch_id: "_inlined_" }
|
||||
- match: { watch_record.trigger_event.type: "manual" }
|
||||
- match: { watch_record.state: "executed" }
|
||||
- match: { watch_record._status.state.active: true }
|
||||
- match: { watch_record._status.actions.indexme.ack.state: "ackable" }
|
||||
- match: { watch_record.status.state.active: true }
|
||||
- match: { watch_record.status.actions.indexme.ack.state: "ackable" }
|
||||
|
||||
---
|
||||
"Execute unknown watch results in 404":
|
||||
|
|
|
@ -54,4 +54,4 @@ teardown:
|
|||
|
||||
- match: { found : true }
|
||||
- match: { _id: "my_watch" }
|
||||
- match: { _status.state.active: false }
|
||||
- match: { status.state.active: false }
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
*/
|
||||
package org.elasticsearch.upgrades;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
@ -20,6 +22,7 @@ import org.elasticsearch.common.xcontent.XContentType;
|
|||
import org.elasticsearch.test.rest.ESRestTestCase;
|
||||
import org.elasticsearch.test.rest.yaml.ObjectPath;
|
||||
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
|
||||
import org.elasticsearch.xpack.watcher.watch.Watch;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -31,6 +34,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_TEMPLATE_NAME;
|
||||
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.loggingAction;
|
||||
import static org.elasticsearch.xpack.watcher.client.WatchSourceBuilders.watchBuilder;
|
||||
|
@ -104,6 +108,20 @@ public class WatchBackwardsCompatibilityIT extends ESRestTestCase {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean preserveIndicesUponCompletion() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Settings restClientSettings() {
|
||||
String token = "Basic " + Base64.getEncoder()
|
||||
.encodeToString("elastic:changeme".getBytes(StandardCharsets.UTF_8));
|
||||
return Settings.builder()
|
||||
.put(ThreadContext.PREFIX + ".Authorization", token)
|
||||
.build();
|
||||
}
|
||||
|
||||
public void testWatcherStats() throws Exception {
|
||||
executeAgainstAllNodes(client ->
|
||||
assertOK(client.performRequest("GET", "/_xpack/watcher/stats"))
|
||||
|
@ -128,15 +146,12 @@ public class WatchBackwardsCompatibilityIT extends ESRestTestCase {
|
|||
ContentType.APPLICATION_JSON);
|
||||
|
||||
executeAgainstAllNodes(client -> {
|
||||
assertOK(client.performRequest("PUT", "/_xpack/watcher/watch/my-watch",
|
||||
Collections.emptyMap(), entity));
|
||||
fakeUpgradeFrom5x(client);
|
||||
|
||||
assertOK(client.performRequest("PUT", "/_xpack/watcher/watch/my-watch", Collections.emptyMap(), entity));
|
||||
assertOK(client.performRequest("GET", "/_xpack/watcher/watch/my-watch"));
|
||||
|
||||
assertOK(client.performRequest("POST", "/_xpack/watcher/watch/my-watch/_execute"));
|
||||
|
||||
assertOK(client.performRequest("PUT", "/_xpack/watcher/watch/my-watch/_deactivate"));
|
||||
|
||||
assertOK(client.performRequest("PUT", "/_xpack/watcher/watch/my-watch/_activate"));
|
||||
});
|
||||
}
|
||||
|
@ -156,24 +171,26 @@ public class WatchBackwardsCompatibilityIT extends ESRestTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean preserveIndicesUponCompletion() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Settings restClientSettings() {
|
||||
String token = "Basic " + Base64.getEncoder()
|
||||
.encodeToString("elastic:changeme".getBytes(StandardCharsets.UTF_8));
|
||||
return Settings.builder()
|
||||
.put(ThreadContext.PREFIX + ".Authorization", token)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void assertOK(Response response) {
|
||||
assertThat(response.getStatusLine().getStatusCode(), anyOf(equalTo(200), equalTo(201)));
|
||||
}
|
||||
|
||||
// This is needed for fake the upgrade from 5.x to 6.0, where a new watches template is created, that contains mapping for the status
|
||||
// field, as _status will be moved to status
|
||||
// This can be removed once the upgrade API supports everything
|
||||
private void fakeUpgradeFrom5x(RestClient client) throws IOException {
|
||||
BytesReference mappingJson = jsonBuilder().startObject().startObject("properties").startObject("status")
|
||||
.field("type", "object")
|
||||
.field("enabled", false)
|
||||
.field("dynamic", true)
|
||||
.endObject().endObject().endObject()
|
||||
.bytes();
|
||||
HttpEntity data = new ByteArrayEntity(mappingJson.toBytesRef().bytes, ContentType.APPLICATION_JSON);
|
||||
|
||||
Response response = client.performRequest("PUT", "/" + Watch.INDEX + "/_mapping/" + Watch.DOC_TYPE, Collections.emptyMap(), data);
|
||||
assertOK(response);
|
||||
}
|
||||
|
||||
private Nodes buildNodeAndVersions() throws IOException {
|
||||
Response response = client().performRequest("GET", "_nodes");
|
||||
ObjectPath objectPath = ObjectPath.createFromResponse(response);
|
||||
|
|
Loading…
Reference in New Issue