There may be current executions still going on during stopping.
We should try to wait for the current executions to have completed.
Otherwise we can run into a situation where we didn't delete the watch from the .triggered_watches index,
but did insert into the history index. Upon start this can lead to DocumentAlreadyExistsException,
because we already stored the history record during shutdown...
Introduced `CurrentExecutions` to handle this synchronization.
(we always first store the watch record and then remove the triggered watch)
Original commit: elastic/x-pack-elasticsearch@89c4a8d8ad
This commit adds support for indexing multiple documents with the `index` action. This is done by introducing a special `_doc` field. During action execution, the `_doc` field will be looked up in the payload. If found, the value of the field will be considered as the document that needs to be indexed. If the value is an array of objects, each object in that array will be treated as a separate document and all the documents in the array will be bulk indexed.
This commit also changes the result of the action to hold `XContentSource` rather than a payload (to avoid Map creation explosions). Th `XContentSource` was also extended to support lists.
Original commit: elastic/x-pack-elasticsearch@86f454b029
The `compare` condition result will now hold all resolved values, keyed by their associated parameter place holder strings.
Original commit: elastic/x-pack-elasticsearch@f930c77d54
This change adds tests to ack a subset of a watch's actions, use a different throttle period per action in a watch, also adds tests to make sure that both the watch level and global level throttle_period are applied correctly.
Also updates the REST tests to make sure that throttle periods can be set at a watch and action level and are returned from the GET API.
Original commit: elastic/x-pack-elasticsearch@4b006c7830
Until today it was required to provide a trigger event as part of the execute API. There are two issues with it:
1. It's not user friendly (you'd expect that the execute API would just work with just pointing to the watch)
2. The API could expose inconsistencies where on one hand it points to a watch (with a well defined trigger) on the other it enabled the user to provide completely different trigger (of a different type)
This change enable supporting default triggers by enabling the trigger engine to create a simulated trigger event. This enables the execute API to look up the trigger type of the pointed watch, and ask the trigger service to simulate an event for it. It is still possible to override the trigger event data by providing it via the `trigger_data` parameter in the API.
This simplifies the execute API and prepares it for future trigger types as well.
- This commit add missing integration tests for the execute API
- Also, removed unused `setIgnoreThrottling` from the execute request/builder.
Original commit: elastic/x-pack-elasticsearch@b494ae62e6
This change allows the httpinput to receive non json formatted data from a http endpoint
(such as the elasticsearch _cat apis). If non json is read it will be stored in the `payload._value` in the same
way that the `ScriptTransform` handles non map/json data returned by transforming scripts.
Added response_content_type to http input so that the expected content type in the response can be configured. This accepts `yaml`, `json` and `text` but will be overridden by the http headers.
Original commit: elastic/x-pack-elasticsearch@753d37f14e
Now that the watch record is write once and never read/parsed. We can de-normalize its format (the structure of the `watch_record` document) such it'd be optimal for searching and aggregating.
- `execution_result` renamed to `result` (for minimal verbosity)
- the structure of `trigger_event` changed to:
```
{
"trigger_event" : {
"type" : "<trigger_type>",
"triggered_time" : "<datetime>",
"<trigger_type>" : { // type specific data (optional) }
}
}
```
- the structure of `input` results changed to:
```
{
"result" : {
"input" : {
"type" : "<input_type>",
"payload" : { // the payload },
"<input_type>" : { // custom result fields per type (optional) }
},
...
}
}
```
- the structure of `condition` results changed to:
```
{
"result" : {
...
"condition" : {
"type" : "<condition_type>",
"met" : true | false,
"<condition_type>" : { // custom result fields per type (optional) }
},
...
}
}
```
- the structure of `transform` results changed to:
```
{
"result" : {
...
"transform" : {
"type" : "<transform_type>",
"payload" : { // the transformed payload }
"<transform_type>" : { // custom result fields per type (optional) }
},
...
}
}
```
- the structure of `actions` results changed to:
```
{
"result" : {
...
"actions" : [
{
"id" : "<action_id>"
"type" : "<action_type>",
"status" : "success" | "failure" | "simulated" | "throttled",
"reason" : "holds the reasoning if status is either success or throttled",
"transform" : { // action level transform result (if applicable)}
"<action_type>" : { // custom result fields per type (optional) }
},
...
]
}
}
```
Original commit: elastic/x-pack-elasticsearch@98466d4b83
The queued watches metric gives insight into the watches that are queued for execution.
Per watch that is queued, executing information is shared, like the `watch_id`,
when the watch was triggered and when execution started.
Original commit: elastic/x-pack-elasticsearch@deb5ddfde2
Before WatchRecord was used to keep track of an execution of a Watch and used to store actual end results to it before sealing it. (for example build dashboard on the history indices)
The keeping track of an execution has been moved from WatchRecord to TriggeredWatch. If a watch triggers a TriggeredWatch is stored. The TriggeredWatch has its own index and only the watch_id (is part of id), trigger event and state is stored. If the execution of a Watch has finished (regardless if it was successfully) a WatchRecord is stored in a history index and the TriggeredWatch is deleted.
When a watch is getting executedtThe triggered watch is used the create the watch context.
Also the WatchRecord.State has been removed to its own enum class named ExecutionState. The CHECKING value has been removed, because it wasn't really used. The CHECKING state was set when the execution began, but it was never persisted and because of this state has also been removed from triggered watch.
By separating the result of a watch execution we are more flexible to in the future change the document format of WatchRecord. The history indices will be used by users to build analytics on top of watcher. Also the history indices become truely append only indices.
When update the watch status, only change the status part with the update api
Also set the version when we delete the watch on the in memory instance enforce more ensureStarted() in the components
Removed all watch record and result parsing code (actions, conditions, inputs and transforms)
Original commit: elastic/x-pack-elasticsearch@8f5ffdac13
- Consolidated setting validation under `WatcherSettingsValidation`
- `WatcherSettingsException` is now only used for settings errors
We need this consolidation as Guice doesn't deal well with exceptions in constructors. So instead, `WatcherSettingsValidation` can be injected and used as a registry for settings errors and then, since it's a service, if there any registered errors, it'll throw `WatcherSettingsException` when it's started.
Fixeselastic/elasticsearch#539
Original commit: elastic/x-pack-elasticsearch@2c1895d18c
The HttpClient class tried to use the truststore as a keystore for watcher with Shield fallback.
This is trappy because in Shield, the default is to only have a keystore that also acts as the
truststore, so the fallback would probably fail in most cases. Additionally, support was missing
for a keystore that had a separate key password.
The new behavior allows for specifying both a keystore and a truststore. If only a keystore is
specified, it will also be used as the truststore. If neither is defined, the system truststore will
be used. All settings fallback to shield settings.
Closeselastic/elasticsearch#480
Original commit: elastic/x-pack-elasticsearch@ad02814806
- now it's possible to ack specific actions via the `Ack Watch API`
- Added tests for acking specific actions
- Changed the watch status structure such that the action ack state can be referred to by `status.actions.<action_id>.ack` (instead of `status.actions.<action_id>.ack_status`... removed the extra redundant "_status")
- As part of this work, also added validation for watch/action ids, such that we disallow having whitespaces in them.
- Updated the docs around acking & throttling of watch actions
Closeselastic/elasticsearch#531Closeselastic/elasticsearch#537
Original commit: elastic/x-pack-elasticsearch@813e601bf5
- HttpResponse now holds the response headers
- Added specific support for content type of the response, based on which we create the xcontent payload.
Original commit: elastic/x-pack-elasticsearch@beae27f576
This change add the actual length of time a watch spends executing. This is useful to find watches that take long to execute to pinpoint those watches that may be candidates for throttling.
Add the execution_duration as a number of milliseconds rather than a timevalue so it can be aggregated from the watch_history index.
Original commit: elastic/x-pack-elasticsearch@0036468f55
Until now, acking and throttling functionality was applied at the watch level. This has major drawbacks in different aspects:
- When multiple actions are defined on a watch, acking a watch effectively acks all the actions. This is conceptually wrong. Say you have two actions: `email` and `index`. It's very likely you'd like to ack the email action (to avoid receiving too many emails) but at the same time continue indexing the data in the `index` action. Right now it's not possible.
- Different actions types may require different throttling. An `email` action probably needs a longer throttle period compared to an `index` action. Also for different `webhook` actions, the throttling is ultimately determined by the 3rd party system that is called.
This commit changes how we do throttling & acking. Moving this functionality to the action level. Now, when acking, each action in the watch will be acked separately. During executiong, each action will determine whether it needs to be throttled or not. The throttler is not associated with the action, not with the watch.
The throttle period was enhanced. There is a default throttle period that is configured for watcher as a whole (using the `watcher.execution.default_throttle_period` setting. Next to that, each `watch` can define its own `throttle_period` that can serve as the default throttle period for the actions in the watch. Lastly, each action can have its own throttle period set.
Since the throttler is now an action "thing", the `throttle` package was renamed to `throttler` and moved under the `actions` package. Also, `WatchThrottler` was renamed to `ActionThrottler`.
With this change, the `Watch Execute API` changed as well. Now, when executing a watch, you can define an execution mode per action. The execution mode offers 4 types of execution:
- `execute`: executes the watch normally (actually executing the action and it may be throttled)
- `force_execute`: skips/ignores throttling and executes the watch
- `simulate`: simulates the watch execution yet it may be throttled
- `force_simulate`: skips/ignores throttling and simulates the watch execution
As part of this change, the structure of the watch status changed along with the xconent representing the `watch_record`. A new `ActionStatus` was introduced (as part of the `WatchStatus`) and is always set for every action in the watch. This status holds:
- the current state of the action (`ackable`, `awaits_successful_execution`, `acked`)
- the last execution state (success/failure + reason)
- the last successful execution state
- the last throttle state (timestamp + reason)
Original commit: elastic/x-pack-elasticsearch@32c2985ed8
The following additional information will be shown per watch that is executing: `watch_id`, `watch_execution_id`, `triggered_time`, `execution_time`, `execution_phase` (whether it is execution an input, condition or an action) and `stack_trace` (useful for us when a customer reports an issue :) ).
The stats api will by default include the executing watches in the response. In order to control this, a `metric` option has been added, which can be specified as query string argument or as last path element in the stats api url. By default the watcher stats API will only return the basic statistics that are already there.
The `metric` option has the following values:
* `current_watches` - Include the current executing watches in the response.
* `_all` - Include all metrics in the stats response. Not very useful now, but when we expose more metrics in this api it will be more useful.
Original commit: elastic/x-pack-elasticsearch@093bef9bb3
Until today we could not search on the `met` field in the condition result. The reason for that is that this field was index as part of the condition result type only, and we disable the indexing for all condition results (to avoid mapping conflicts).
This commit pulls the `met` condition one level higher and enables its mapping. For now (beta1) we can live with the duplication of the condition result source (were the `met` is not placed in both the condition result type and on the condition result itself). Later we should remove the duplication though.
An example of a "compare" condition result now looks like:
```
"condition": {
"met": true,
"compare": {
"met": true,
"resolved_value": 1
}
}
```
Original commit: elastic/x-pack-elasticsearch@74a3372c25
A simple `condition` that compares a path into the model in the execution context to a value. The comparison is based on the following possible operators: `eq`, `not_eq`, `lt`, `lte`, `gt`, `gte`.
The following example shows a `compare` condition that checks if the total hits in the payload is greater or equal to 5.
```
{
"compare" : {
"ctx.payload.hits.total" : { "gte" : "5" }
}
}
```
Original commit: elastic/x-pack-elasticsearch@6d4f2bbf10
Fixed the mappings of the index action fields such that the `index` and `type` of the index response won't be analyzed.
Original commit: elastic/x-pack-elasticsearch@5db8bf6a33
rely on http header to be send for Shield authentication
and finally omit the manage_watcher role from the test user.
Original commit: elastic/x-pack-elasticsearch@57a6366119