From 4f1866db69889a845f6d0f67b88a798b9e68fd31 Mon Sep 17 00:00:00 2001 From: lcawley Date: Thu, 14 Dec 2017 10:52:49 -0800 Subject: [PATCH 01/12] [DOCS] Updated titles of ML APIs Original commit: elastic/x-pack-elasticsearch@3b3d856a8963008171337c76a9f3f2bbbf2ed0a2 --- docs/en/rest-api/ml/close-job.asciidoc | 5 ++++- docs/en/rest-api/ml/delete-datafeed.asciidoc | 5 ++++- docs/en/rest-api/ml/delete-job.asciidoc | 5 ++++- docs/en/rest-api/ml/delete-snapshot.asciidoc | 5 ++++- docs/en/rest-api/ml/flush-job.asciidoc | 5 ++++- docs/en/rest-api/ml/forecast.asciidoc | 5 ++++- docs/en/rest-api/ml/get-bucket.asciidoc | 5 ++++- docs/en/rest-api/ml/get-category.asciidoc | 5 ++++- docs/en/rest-api/ml/get-datafeed-stats.asciidoc | 5 ++++- docs/en/rest-api/ml/get-datafeed.asciidoc | 5 ++++- docs/en/rest-api/ml/get-influencer.asciidoc | 5 ++++- docs/en/rest-api/ml/get-job-stats.asciidoc | 5 ++++- docs/en/rest-api/ml/get-job.asciidoc | 5 ++++- docs/en/rest-api/ml/get-overall-buckets.asciidoc | 5 ++++- docs/en/rest-api/ml/get-record.asciidoc | 5 ++++- docs/en/rest-api/ml/get-snapshot.asciidoc | 5 ++++- docs/en/rest-api/ml/open-job.asciidoc | 5 ++++- docs/en/rest-api/ml/post-data.asciidoc | 5 ++++- docs/en/rest-api/ml/preview-datafeed.asciidoc | 5 ++++- docs/en/rest-api/ml/put-datafeed.asciidoc | 5 ++++- docs/en/rest-api/ml/put-job.asciidoc | 5 ++++- docs/en/rest-api/ml/revert-snapshot.asciidoc | 5 ++++- docs/en/rest-api/ml/start-datafeed.asciidoc | 5 ++++- docs/en/rest-api/ml/stop-datafeed.asciidoc | 5 ++++- docs/en/rest-api/ml/update-datafeed.asciidoc | 5 ++++- docs/en/rest-api/ml/update-job.asciidoc | 5 ++++- docs/en/rest-api/ml/update-snapshot.asciidoc | 5 ++++- docs/en/rest-api/ml/validate-detector.asciidoc | 5 ++++- docs/en/rest-api/ml/validate-job.asciidoc | 5 ++++- 29 files changed, 116 insertions(+), 29 deletions(-) diff --git a/docs/en/rest-api/ml/close-job.asciidoc b/docs/en/rest-api/ml/close-job.asciidoc index 1e6ac728268..e29442da47d 100644 --- a/docs/en/rest-api/ml/close-job.asciidoc +++ b/docs/en/rest-api/ml/close-job.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-close-job]] -=== Close Jobs +=== Close Jobs API +++++ +Close Jobs +++++ The close job API enables you to close one or more jobs. A job can be opened and closed multiple times throughout its lifecycle. diff --git a/docs/en/rest-api/ml/delete-datafeed.asciidoc b/docs/en/rest-api/ml/delete-datafeed.asciidoc index aa2a033a4ba..c50e88734ee 100644 --- a/docs/en/rest-api/ml/delete-datafeed.asciidoc +++ b/docs/en/rest-api/ml/delete-datafeed.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-delete-datafeed]] -=== Delete {dfeeds-cap} +=== Delete {dfeeds-cap} API +++++ +Delete {dfeeds-cap} +++++ The delete {dfeed} API enables you to delete an existing {dfeed}. diff --git a/docs/en/rest-api/ml/delete-job.asciidoc b/docs/en/rest-api/ml/delete-job.asciidoc index 3b02fb7c1ce..1f746e55d9b 100644 --- a/docs/en/rest-api/ml/delete-job.asciidoc +++ b/docs/en/rest-api/ml/delete-job.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-delete-job]] -=== Delete Jobs +=== Delete Jobs API +++++ +Delete Jobs +++++ The delete job API enables you to delete an existing anomaly detection job. diff --git a/docs/en/rest-api/ml/delete-snapshot.asciidoc b/docs/en/rest-api/ml/delete-snapshot.asciidoc index c0530d013c8..16e9969bcac 100644 --- a/docs/en/rest-api/ml/delete-snapshot.asciidoc +++ b/docs/en/rest-api/ml/delete-snapshot.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-delete-snapshot]] -=== Delete Model Snapshots +=== Delete Model Snapshots API +++++ +Delete Model Snapshots +++++ The delete model snapshot API enables you to delete an existing model snapshot. diff --git a/docs/en/rest-api/ml/flush-job.asciidoc b/docs/en/rest-api/ml/flush-job.asciidoc index 56b488ac0fa..0a4c055113d 100644 --- a/docs/en/rest-api/ml/flush-job.asciidoc +++ b/docs/en/rest-api/ml/flush-job.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-flush-job]] -=== Flush Jobs +=== Flush Jobs API +++++ +Flush Jobs +++++ The flush job API forces any buffered data to be processed by the job. diff --git a/docs/en/rest-api/ml/forecast.asciidoc b/docs/en/rest-api/ml/forecast.asciidoc index 820b7c4d79d..0cda58c4aa7 100644 --- a/docs/en/rest-api/ml/forecast.asciidoc +++ b/docs/en/rest-api/ml/forecast.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-forecast]] -=== Forecast Jobs +=== Forecast Jobs API +++++ +Forecast Jobs +++++ The forecast jobs API uses historical behavior to predict the future behavior of a time series. diff --git a/docs/en/rest-api/ml/get-bucket.asciidoc b/docs/en/rest-api/ml/get-bucket.asciidoc index 4c7f3eb7f6e..f62b9d56c3e 100644 --- a/docs/en/rest-api/ml/get-bucket.asciidoc +++ b/docs/en/rest-api/ml/get-bucket.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-get-bucket]] -=== Get Buckets +=== Get Buckets API +++++ +Get Buckets +++++ The get bucket API enables you to retrieve job results for one or more buckets. diff --git a/docs/en/rest-api/ml/get-category.asciidoc b/docs/en/rest-api/ml/get-category.asciidoc index e781da7bc25..a0eae894de0 100644 --- a/docs/en/rest-api/ml/get-category.asciidoc +++ b/docs/en/rest-api/ml/get-category.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-get-category]] -=== Get Categories +=== Get Categories API +++++ +Get Categories +++++ The get categories API enables you to retrieve job results for one or more categories. diff --git a/docs/en/rest-api/ml/get-datafeed-stats.asciidoc b/docs/en/rest-api/ml/get-datafeed-stats.asciidoc index bb6e9bfafa2..4ee799271af 100644 --- a/docs/en/rest-api/ml/get-datafeed-stats.asciidoc +++ b/docs/en/rest-api/ml/get-datafeed-stats.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-get-datafeed-stats]] -=== Get {dfeed-cap} Statistics +=== Get {dfeed-cap} Statistics API +++++ +Get {dfeed-cap} Statistics +++++ The get {dfeed} statistics API enables you to retrieve usage information for {dfeeds}. diff --git a/docs/en/rest-api/ml/get-datafeed.asciidoc b/docs/en/rest-api/ml/get-datafeed.asciidoc index e91e6d58c9a..ac612ae6943 100644 --- a/docs/en/rest-api/ml/get-datafeed.asciidoc +++ b/docs/en/rest-api/ml/get-datafeed.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-get-datafeed]] -=== Get {dfeeds-cap} +=== Get {dfeeds-cap} API +++++ +Get {dfeeds-cap} +++++ The get {dfeeds} API enables you to retrieve configuration information for {dfeeds}. diff --git a/docs/en/rest-api/ml/get-influencer.asciidoc b/docs/en/rest-api/ml/get-influencer.asciidoc index d8fe87d11ed..125197373bf 100644 --- a/docs/en/rest-api/ml/get-influencer.asciidoc +++ b/docs/en/rest-api/ml/get-influencer.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-get-influencer]] -=== Get Influencers +=== Get Influencers API +++++ +Get Influencers +++++ The get influencers API enables you to retrieve job results for one or more influencers. diff --git a/docs/en/rest-api/ml/get-job-stats.asciidoc b/docs/en/rest-api/ml/get-job-stats.asciidoc index ae9e8881803..d9d2273330b 100644 --- a/docs/en/rest-api/ml/get-job-stats.asciidoc +++ b/docs/en/rest-api/ml/get-job-stats.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-get-job-stats]] -=== Get Job Statistics +=== Get Job Statistics API +++++ +Get Job Statistics +++++ The get jobs API enables you to retrieve usage information for jobs. diff --git a/docs/en/rest-api/ml/get-job.asciidoc b/docs/en/rest-api/ml/get-job.asciidoc index 5ad036692e2..db77f1fcdac 100644 --- a/docs/en/rest-api/ml/get-job.asciidoc +++ b/docs/en/rest-api/ml/get-job.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-get-job]] -=== Get Jobs +=== Get Jobs API +++++ +Get Jobs +++++ The get jobs API enables you to retrieve configuration information for jobs. diff --git a/docs/en/rest-api/ml/get-overall-buckets.asciidoc b/docs/en/rest-api/ml/get-overall-buckets.asciidoc index e2ced2989f3..eee6cec9c04 100644 --- a/docs/en/rest-api/ml/get-overall-buckets.asciidoc +++ b/docs/en/rest-api/ml/get-overall-buckets.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-get-overall-buckets]] -=== Get Overall Buckets +=== Get Overall Buckets API +++++ +Get Overall Buckets +++++ This API enables you to retrieve overall bucket results that summarize the bucket results of multiple jobs. diff --git a/docs/en/rest-api/ml/get-record.asciidoc b/docs/en/rest-api/ml/get-record.asciidoc index f35fea7d68b..abe00f6547f 100644 --- a/docs/en/rest-api/ml/get-record.asciidoc +++ b/docs/en/rest-api/ml/get-record.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-get-record]] -=== Get Records +=== Get Records API +++++ +Get Records +++++ The get records API enables you to retrieve anomaly records for a job. diff --git a/docs/en/rest-api/ml/get-snapshot.asciidoc b/docs/en/rest-api/ml/get-snapshot.asciidoc index 5d0cefd42b4..53ce0a617a3 100644 --- a/docs/en/rest-api/ml/get-snapshot.asciidoc +++ b/docs/en/rest-api/ml/get-snapshot.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-get-snapshot]] -=== Get Model Snapshots +=== Get Model Snapshots API +++++ +Get Model Snapshots +++++ The get model snapshots API enables you to retrieve information about model snapshots. diff --git a/docs/en/rest-api/ml/open-job.asciidoc b/docs/en/rest-api/ml/open-job.asciidoc index e7d4e9842a2..a1dec2d684c 100644 --- a/docs/en/rest-api/ml/open-job.asciidoc +++ b/docs/en/rest-api/ml/open-job.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-open-job]] -=== Open Jobs +=== Open Jobs API +++++ +Open Jobs +++++ A job must be opened in order for it to be ready to receive and analyze data. A job can be opened and closed multiple times throughout its lifecycle. diff --git a/docs/en/rest-api/ml/post-data.asciidoc b/docs/en/rest-api/ml/post-data.asciidoc index 9d3e1b1f8dd..5daeb8b2f67 100644 --- a/docs/en/rest-api/ml/post-data.asciidoc +++ b/docs/en/rest-api/ml/post-data.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-post-data]] -=== Post Data to Jobs +=== Post Data to Jobs API +++++ +Post Data to Jobs +++++ The post data API enables you to send data to an anomaly detection job for analysis. diff --git a/docs/en/rest-api/ml/preview-datafeed.asciidoc b/docs/en/rest-api/ml/preview-datafeed.asciidoc index e9bf76b736f..f3012170631 100644 --- a/docs/en/rest-api/ml/preview-datafeed.asciidoc +++ b/docs/en/rest-api/ml/preview-datafeed.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-preview-datafeed]] -=== Preview {dfeeds-cap} +=== Preview {dfeeds-cap} API +++++ +Preview {dfeeds-cap} +++++ The preview {dfeed} API enables you to preview a {dfeed}. diff --git a/docs/en/rest-api/ml/put-datafeed.asciidoc b/docs/en/rest-api/ml/put-datafeed.asciidoc index a37b680e9f1..9ef0948a88b 100644 --- a/docs/en/rest-api/ml/put-datafeed.asciidoc +++ b/docs/en/rest-api/ml/put-datafeed.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-put-datafeed]] -=== Create {dfeeds-cap} +=== Create {dfeeds-cap} API +++++ +Create {dfeeds-cap} +++++ The create {dfeed} API enables you to instantiate a {dfeed}. diff --git a/docs/en/rest-api/ml/put-job.asciidoc b/docs/en/rest-api/ml/put-job.asciidoc index 631f4437adb..ea8e73c14ce 100644 --- a/docs/en/rest-api/ml/put-job.asciidoc +++ b/docs/en/rest-api/ml/put-job.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-put-job]] -=== Create Jobs +=== Create Jobs API +++++ +Create Jobs +++++ The create job API enables you to instantiate a job. diff --git a/docs/en/rest-api/ml/revert-snapshot.asciidoc b/docs/en/rest-api/ml/revert-snapshot.asciidoc index 6cc6174decf..a835c0f4db3 100644 --- a/docs/en/rest-api/ml/revert-snapshot.asciidoc +++ b/docs/en/rest-api/ml/revert-snapshot.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-revert-snapshot]] -=== Revert Model Snapshots +=== Revert Model Snapshots API +++++ +Revert Model Snapshots +++++ The revert model snapshot API enables you to revert to a specific snapshot. diff --git a/docs/en/rest-api/ml/start-datafeed.asciidoc b/docs/en/rest-api/ml/start-datafeed.asciidoc index 65893fb918e..147186fbfc1 100644 --- a/docs/en/rest-api/ml/start-datafeed.asciidoc +++ b/docs/en/rest-api/ml/start-datafeed.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-start-datafeed]] -=== Start {dfeeds-cap} +=== Start {dfeeds-cap} API +++++ +Start {dfeeds-cap} +++++ A {dfeed} must be started in order to retrieve data from {es}. A {dfeed} can be started and stopped multiple times throughout its lifecycle. diff --git a/docs/en/rest-api/ml/stop-datafeed.asciidoc b/docs/en/rest-api/ml/stop-datafeed.asciidoc index ab3a81c4c01..ca616b67404 100644 --- a/docs/en/rest-api/ml/stop-datafeed.asciidoc +++ b/docs/en/rest-api/ml/stop-datafeed.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-stop-datafeed]] -=== Stop {dfeeds-cap} +=== Stop {dfeeds-cap} API +++++ +Stop {dfeeds-cap} +++++ The stop {dfeeds} API enables you to stop one or more {dfeeds}. diff --git a/docs/en/rest-api/ml/update-datafeed.asciidoc b/docs/en/rest-api/ml/update-datafeed.asciidoc index 3651afc094c..a17b7892534 100644 --- a/docs/en/rest-api/ml/update-datafeed.asciidoc +++ b/docs/en/rest-api/ml/update-datafeed.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-update-datafeed]] -=== Update {dfeeds-cap} +=== Update {dfeeds-cap} API +++++ +Update {dfeeds-cap} +++++ The update {dfeed} API enables you to update certain properties of a {dfeed}. diff --git a/docs/en/rest-api/ml/update-job.asciidoc b/docs/en/rest-api/ml/update-job.asciidoc index 7f21e46c9b4..34e50215c09 100644 --- a/docs/en/rest-api/ml/update-job.asciidoc +++ b/docs/en/rest-api/ml/update-job.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-update-job]] -=== Update Jobs +=== Update Jobs API +++++ +Update Jobs +++++ The update job API enables you to update certain properties of a job. diff --git a/docs/en/rest-api/ml/update-snapshot.asciidoc b/docs/en/rest-api/ml/update-snapshot.asciidoc index bb31553cd4c..30a2c0c5143 100644 --- a/docs/en/rest-api/ml/update-snapshot.asciidoc +++ b/docs/en/rest-api/ml/update-snapshot.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-update-snapshot]] -=== Update Model Snapshots +=== Update Model Snapshots API +++++ +Update Model Snapshots +++++ The update model snapshot API enables you to update certain properties of a snapshot. diff --git a/docs/en/rest-api/ml/validate-detector.asciidoc b/docs/en/rest-api/ml/validate-detector.asciidoc index 37648087845..60c0c7f0646 100644 --- a/docs/en/rest-api/ml/validate-detector.asciidoc +++ b/docs/en/rest-api/ml/validate-detector.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-valid-detector]] -=== Validate Detectors +=== Validate Detectors API +++++ +Validate Detectors +++++ The validate detectors API validates detector configuration information. diff --git a/docs/en/rest-api/ml/validate-job.asciidoc b/docs/en/rest-api/ml/validate-job.asciidoc index 5d0f0b7aa93..18a6e96da32 100644 --- a/docs/en/rest-api/ml/validate-job.asciidoc +++ b/docs/en/rest-api/ml/validate-job.asciidoc @@ -1,6 +1,9 @@ [role="xpack"] [[ml-valid-job]] -=== Validate Jobs +=== Validate Jobs API +++++ +Validate Jobs +++++ The validate jobs API validates job configuration information. From 78f7c0e27af217f248efc3c1b0b5d84e5796e6ba Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Fri, 15 Dec 2017 05:56:01 -0800 Subject: [PATCH 02/12] Fix license messaging for Logstash functionality (elastic/x-pack-elasticsearch#3268) * Fix license messaging for Logstash functionality With a Basic license, users are still able to perform CRUD operations on the `.logstash` index, therefore manage their Logstash pipelines. However, Logstash itself will not pick up any changes from this index and act on them. With an expired license Logstash functionality continues to operate as normal. * Fixing messages after feedback * Removing extraneous tabs at end of line * Fixing typo Original commit: elastic/x-pack-elasticsearch@bc069cf00ff865056ee53fd3e7c79b325c68dcee --- .../java/org/elasticsearch/license/XPackLicenseState.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugin/src/main/java/org/elasticsearch/license/XPackLicenseState.java b/plugin/src/main/java/org/elasticsearch/license/XPackLicenseState.java index e5c33c782eb..4a51aace3ac 100644 --- a/plugin/src/main/java/org/elasticsearch/license/XPackLicenseState.java +++ b/plugin/src/main/java/org/elasticsearch/license/XPackLicenseState.java @@ -49,7 +49,7 @@ public class XPackLicenseState { "Machine learning APIs are disabled" }); messages.put(XPackPlugin.LOGSTASH, new String[] { - "Logstash specific APIs are disabled. You can continue to manage and poll stored configurations" + "Logstash will continue to poll centrally-managed pipelines" }); messages.put(XPackPlugin.DEPRECATION, new String[] { "Deprecation APIs are disabled" @@ -201,8 +201,7 @@ public class XPackLicenseState { case STANDARD: case GOLD: case PLATINUM: - return new String[] { "Logstash specific APIs will be disabled, but you can continue to manage " + - "and poll stored configurations" }; + return new String[] { "Logstash will no longer poll for centrally-managed pipelines" }; } break; } From 758433a0fa36e8d9eb7387e49b13b046d70bc4cd Mon Sep 17 00:00:00 2001 From: Alexander Reelsen Date: Fri, 15 Dec 2017 15:23:57 +0100 Subject: [PATCH 03/12] Monitoring: Ensure all monitoring watches filter by timestamp (elastic/x-pack-elasticsearch#3238) Only the Logstash and Kibana version mismatch watches contain a time filter, the others are only sorting by timestamp. In combination with searching in all `.monitoring-es-*` indices, this is IMO pretty resource intensive, as we cannot exit early on any search request. This commit adds time based filters to remaining three watches, using the same range than the other two. Original commit: elastic/x-pack-elasticsearch@3eb6bf0de2b9fb36564717e22a9f406457c0bddc --- .../monitoring/watches/elasticsearch_cluster_status.json | 7 +++++++ .../monitoring/watches/elasticsearch_version_mismatch.json | 7 +++++++ .../monitoring/watches/xpack_license_expiration.json | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/plugin/src/main/resources/monitoring/watches/elasticsearch_cluster_status.json b/plugin/src/main/resources/monitoring/watches/elasticsearch_cluster_status.json index e5639c0bb1d..c0a13ea63a6 100644 --- a/plugin/src/main/resources/monitoring/watches/elasticsearch_cluster_status.json +++ b/plugin/src/main/resources/monitoring/watches/elasticsearch_cluster_status.json @@ -61,6 +61,13 @@ } ] } + }, + { + "range": { + "timestamp": { + "gte": "now-2m" + } + } } ] } diff --git a/plugin/src/main/resources/monitoring/watches/elasticsearch_version_mismatch.json b/plugin/src/main/resources/monitoring/watches/elasticsearch_version_mismatch.json index 04328cdddb3..7e18c981f0f 100644 --- a/plugin/src/main/resources/monitoring/watches/elasticsearch_version_mismatch.json +++ b/plugin/src/main/resources/monitoring/watches/elasticsearch_version_mismatch.json @@ -54,6 +54,13 @@ } ] } + }, + { + "range": { + "timestamp": { + "gte": "now-2m" + } + } } ] } diff --git a/plugin/src/main/resources/monitoring/watches/xpack_license_expiration.json b/plugin/src/main/resources/monitoring/watches/xpack_license_expiration.json index 2fa2a06249c..a05198a15eb 100644 --- a/plugin/src/main/resources/monitoring/watches/xpack_license_expiration.json +++ b/plugin/src/main/resources/monitoring/watches/xpack_license_expiration.json @@ -51,6 +51,13 @@ "term": { "type": "cluster_stats" } + }, + { + "range": { + "timestamp": { + "gte": "now-2m" + } + } } ] } From b81c90d6fc5b686196a95e0ce0c4f213d7e62a29 Mon Sep 17 00:00:00 2001 From: David Roberts Date: Fri, 15 Dec 2017 14:41:10 +0000 Subject: [PATCH 04/12] [DOCS] Explain ML datafeed run-as integration/limitations (elastic/x-pack-elasticsearch#3311) Docs for elastic/x-pack-elasticsearch#3254 Original commit: elastic/x-pack-elasticsearch@eec3c7cccee810373e7a6a1b34fabd8bdebe90c5 --- docs/en/ml/limitations.asciidoc | 14 ++++++++++++++ docs/en/rest-api/ml/preview-datafeed.asciidoc | 11 +++++++++++ docs/en/rest-api/ml/put-datafeed.asciidoc | 7 +++++++ docs/en/rest-api/ml/start-datafeed.asciidoc | 7 +++++++ docs/en/rest-api/ml/update-datafeed.asciidoc | 7 +++++++ 5 files changed, 46 insertions(+) diff --git a/docs/en/ml/limitations.asciidoc b/docs/en/ml/limitations.asciidoc index 60fc7cafa5f..9a68ce026a2 100644 --- a/docs/en/ml/limitations.asciidoc +++ b/docs/en/ml/limitations.asciidoc @@ -157,3 +157,17 @@ poorer precision worthwhile. If you want to view or change the aggregations that are used in your job, refer to the `aggregations` property in your {dfeed}. For more information, see {ref}/ml-datafeed-resource.html[Datafeed Resources]. + +[float] +=== Security Integration + +When {security} is enabled, a {dfeed} stores the roles of the user who created +or updated the {dfeed} **at that time**. This means that if those roles are +updated then the {dfeed} will subsequently run with the new permissions associated +with the roles. However, if the user's roles are adjusted after creating or +updating the {dfeed} then the {dfeed} will continue to run with the permissions +associated with the original roles. + +A way to update the roles stored within the {dfeed} without changing any other +settings is to submit an empty JSON document (`{}`) to the +{ref}/ml-update-datafeed.html[update {dfeed} API]. diff --git a/docs/en/rest-api/ml/preview-datafeed.asciidoc b/docs/en/rest-api/ml/preview-datafeed.asciidoc index f3012170631..dfb402efa92 100644 --- a/docs/en/rest-api/ml/preview-datafeed.asciidoc +++ b/docs/en/rest-api/ml/preview-datafeed.asciidoc @@ -34,6 +34,17 @@ privileges to use this API. For more information, see //<>. +==== Security Integration + +When {security} is enabled, the {dfeed} query will be previewed using the +credentials of the user calling the preview {dfeed} API. When the {dfeed} +is started it will run the query using the roles of the last user to +create or update it. If the two sets of roles differ then the preview may +not accurately reflect what the {dfeed} will return when started. To avoid +such problems, the same user that creates/updates the {dfeed} should preview +it to ensure it is returning the expected data. + + ==== Examples The following example obtains a preview of the `datafeed-farequote` {dfeed}: diff --git a/docs/en/rest-api/ml/put-datafeed.asciidoc b/docs/en/rest-api/ml/put-datafeed.asciidoc index 9ef0948a88b..2e367273690 100644 --- a/docs/en/rest-api/ml/put-datafeed.asciidoc +++ b/docs/en/rest-api/ml/put-datafeed.asciidoc @@ -87,6 +87,13 @@ For more information, see {xpack-ref}/security-privileges.html[Security Privileges]. //<>. + +==== Security Integration + +When {security} is enabled, your {dfeed} will remember which roles the user who +created it had at the time of creation, and run the query using those same roles. + + ==== Examples The following example creates the `datafeed-total-requests` {dfeed}: diff --git a/docs/en/rest-api/ml/start-datafeed.asciidoc b/docs/en/rest-api/ml/start-datafeed.asciidoc index 147186fbfc1..801984deac0 100644 --- a/docs/en/rest-api/ml/start-datafeed.asciidoc +++ b/docs/en/rest-api/ml/start-datafeed.asciidoc @@ -81,6 +81,13 @@ For more information, see //<>. +==== Security Integration + +When {security} is enabled, your {dfeed} will remember which roles the last +user to create or update it had at the time of creation/update, and run the query +using those same roles. + + ==== Examples The following example starts the `datafeed-it-ops-kpi` {dfeed}: diff --git a/docs/en/rest-api/ml/update-datafeed.asciidoc b/docs/en/rest-api/ml/update-datafeed.asciidoc index a17b7892534..560f3c82ca2 100644 --- a/docs/en/rest-api/ml/update-datafeed.asciidoc +++ b/docs/en/rest-api/ml/update-datafeed.asciidoc @@ -82,6 +82,13 @@ For more information, see {xpack-ref}/security-privileges.html[Security Privileges]. //<>. + +==== Security Integration + +When {security} is enabled, your {dfeed} will remember which roles the user who +updated it had at the time of update, and run the query using those same roles. + + ==== Examples The following example updates the query for the `datafeed-it-ops-kpi` {dfeed} From f518501df4138d03a9ef0c98c63d05baa5045378 Mon Sep 17 00:00:00 2001 From: Alexander Reelsen Date: Fri, 15 Dec 2017 16:00:21 +0100 Subject: [PATCH 05/12] Tests: Ensure that watcher is started in HipchatServiceTests One of those tests requires watcher to be started, so a proper assertBusy() block has been added to this tests. relates elastic/x-pack-elasticsearch#3324 Original commit: elastic/x-pack-elasticsearch@324830316f0943c91017a45a41c980871700a435 --- .../xpack/watcher/test/integration/HipChatServiceTests.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugin/src/test/java/org/elasticsearch/xpack/watcher/test/integration/HipChatServiceTests.java b/plugin/src/test/java/org/elasticsearch/xpack/watcher/test/integration/HipChatServiceTests.java index 6222c59abe6..51bdc8f6692 100644 --- a/plugin/src/test/java/org/elasticsearch/xpack/watcher/test/integration/HipChatServiceTests.java +++ b/plugin/src/test/java/org/elasticsearch/xpack/watcher/test/integration/HipChatServiceTests.java @@ -15,6 +15,8 @@ import org.elasticsearch.test.junit.annotations.TestLogging; import org.elasticsearch.xpack.XPackPlugin; import org.elasticsearch.xpack.XPackSettings; import org.elasticsearch.xpack.XPackSingleNodeTestCase; +import org.elasticsearch.xpack.watcher.WatcherService; +import org.elasticsearch.xpack.watcher.WatcherState; import org.elasticsearch.xpack.watcher.actions.hipchat.HipChatAction; import org.elasticsearch.xpack.watcher.client.WatcherClient; import org.elasticsearch.xpack.watcher.condition.AlwaysCondition; @@ -127,6 +129,8 @@ public class HipChatServiceTests extends XPackSingleNodeTestCase { } public void testWatchWithHipChatAction() throws Exception { + assertBusy(() -> assertThat(getInstanceFromNode(WatcherService.class).state(), is(WatcherState.STARTED))); + HipChatAccount.Profile profile = randomFrom(HipChatAccount.Profile.values()); HipChatMessage.Color color = randomFrom(HipChatMessage.Color.values()); String account; From 5f8a0711f5734d3d841a5ccf3b90a403254d8429 Mon Sep 17 00:00:00 2001 From: Alexander Reelsen Date: Fri, 15 Dec 2017 16:59:29 +0100 Subject: [PATCH 06/12] Watcher: Set index and type dynamically in index action (elastic/x-pack-elasticsearch#3264) The index action allowed to set the id of a document dynamically, however this was not allowed for the index or the type. If a user wants to execute a search, modify the found documents and index them back, then this would only work across a single index and a single type. This change allows the watch writer to just take a search result, read index and type out of that and configure this as part of the index action. On top of that the integration tests have been changed to become fast running unit tests. Original commit: elastic/x-pack-elasticsearch@640b085dd4e0f4d8e4903d391c583878a7932825 --- docs/en/watcher/actions/index.asciidoc | 4 +- .../actions/index/ExecutableIndexAction.java | 56 ++- .../watcher/actions/index/IndexAction.java | 31 +- .../actions/index/IndexActionTests.java | 444 ++++++++++-------- 4 files changed, 289 insertions(+), 246 deletions(-) diff --git a/docs/en/watcher/actions/index.asciidoc b/docs/en/watcher/actions/index.asciidoc index 2585d50e090..f003da74b99 100644 --- a/docs/en/watcher/actions/index.asciidoc +++ b/docs/en/watcher/actions/index.asciidoc @@ -71,5 +71,5 @@ When a `_doc` field exists, if the field holds an object, it is extracted and in as a single document. If the field holds an array of objects, each object is treated as a document and the index action indexes all of them in a bulk. -An `_id` value can be added per document to dynamically set the ID of the indexed -document. +An `_index`, `_type` or `_id` value can be added per document to dynamically set the ID +of the indexed document. diff --git a/plugin/src/main/java/org/elasticsearch/xpack/watcher/actions/index/ExecutableIndexAction.java b/plugin/src/main/java/org/elasticsearch/xpack/watcher/actions/index/ExecutableIndexAction.java index 4e05e9cab6c..ebeec8b9641 100644 --- a/plugin/src/main/java/org/elasticsearch/xpack/watcher/actions/index/ExecutableIndexAction.java +++ b/plugin/src/main/java/org/elasticsearch/xpack/watcher/actions/index/ExecutableIndexAction.java @@ -38,6 +38,8 @@ import static org.elasticsearch.xpack.watcher.support.Exceptions.illegalState; public class ExecutableIndexAction extends ExecutableAction { + private static final String INDEX_FIELD = "_index"; + private static final String TYPE_FIELD = "_type"; private static final String ID_FIELD = "_id"; private final Client client; @@ -71,24 +73,13 @@ public class ExecutableIndexAction extends ExecutableAction { } } - String docId = action.docId; - - // prevent double-setting id - if (data.containsKey(ID_FIELD)) { - if (docId != null) { - throw illegalState("could not execute action [{}] of watch [{}]. " + - "[ctx.payload.{}] or [ctx.payload._doc.{}] were set with [doc_id]. Only set [{}] or [doc_id]", - actionId, ctx.watch().id(), ID_FIELD, ID_FIELD, ID_FIELD); - } - + if (data.containsKey(INDEX_FIELD) || data.containsKey(TYPE_FIELD) || data.containsKey(ID_FIELD)) { data = mutableMap(data); - docId = data.remove(ID_FIELD).toString(); } - IndexRequest indexRequest = new IndexRequest(); - indexRequest.index(action.index); - indexRequest.type(action.docType); - indexRequest.id(docId); + indexRequest.index(getField(actionId, ctx.id().watchId(), "index", data, INDEX_FIELD, action.index)); + indexRequest.type(getField(actionId, ctx.id().watchId(), "type",data, TYPE_FIELD, action.docType)); + indexRequest.id(getField(actionId, ctx.id().watchId(), "id",data, ID_FIELD, action.docId)); data = addTimestampToDocument(data, ctx.executionTime()); BytesReference bytesReference; @@ -97,8 +88,8 @@ public class ExecutableIndexAction extends ExecutableAction { } if (ctx.simulateAction(actionId)) { - return new IndexAction.Simulated(indexRequest.index(), action.docType, docId, new XContentSource(indexRequest.source(), - XContentType.JSON)); + return new IndexAction.Simulated(indexRequest.index(), indexRequest.type(), indexRequest.id(), + new XContentSource(indexRequest.source(), XContentType.JSON)); } IndexResponse response = WatcherClientHelper.execute(ctx.watch(), client, @@ -121,14 +112,17 @@ public class ExecutableIndexAction extends ExecutableAction { throw illegalState("could not execute action [{}] of watch [{}]. failed to index payload data. " + "[_data] field must either hold a Map or an List/Array of Maps", actionId, ctx.watch().id()); } + Map doc = (Map) item; - IndexRequest indexRequest = new IndexRequest(); - indexRequest.index(action.index); - indexRequest.type(action.docType); - if (doc.containsKey(ID_FIELD)) { + if (doc.containsKey(INDEX_FIELD) || doc.containsKey(TYPE_FIELD) || doc.containsKey(ID_FIELD)) { doc = mutableMap(doc); - indexRequest.id(doc.remove(ID_FIELD).toString()); } + + IndexRequest indexRequest = new IndexRequest(); + indexRequest.index(getField(actionId, ctx.id().watchId(), "index", doc, INDEX_FIELD, action.index)); + indexRequest.type(getField(actionId, ctx.id().watchId(), "type",doc, TYPE_FIELD, action.docType)); + indexRequest.id(getField(actionId, ctx.id().watchId(), "id",doc, ID_FIELD, action.docId)); + doc = addTimestampToDocument(doc, ctx.executionTime()); try (XContentBuilder builder = jsonBuilder()) { indexRequest.source(builder.prettyPrint().map(doc)); @@ -163,6 +157,24 @@ public class ExecutableIndexAction extends ExecutableAction { return data; } + /** + * Extracts the specified field out of data map, or alternative falls back to the action value + */ + private String getField(String actionId, String watchId, String name, Map data, String fieldName, String defaultValue) { + Object obj = data.remove(fieldName); + if (obj != null) { + if (defaultValue != null) { + throw illegalState("could not execute action [{}] of watch [{}]. " + + "[ctx.payload.{}] or [ctx.payload._doc.{}] were set together with action [{}] field. Only set one of them", + actionId, watchId, fieldName, fieldName, name); + } else { + return obj.toString(); + } + } + + return defaultValue; + } + /** * Guarantees that the {@code data} is mutable for any code that needs to modify the {@linkplain Map} before using it (e.g., from * singleton, immutable {@code Map}s). diff --git a/plugin/src/main/java/org/elasticsearch/xpack/watcher/actions/index/IndexAction.java b/plugin/src/main/java/org/elasticsearch/xpack/watcher/actions/index/IndexAction.java index 1ffa9ccc5df..f838c88dad3 100644 --- a/plugin/src/main/java/org/elasticsearch/xpack/watcher/actions/index/IndexAction.java +++ b/plugin/src/main/java/org/elasticsearch/xpack/watcher/actions/index/IndexAction.java @@ -25,14 +25,14 @@ public class IndexAction implements Action { public static final String TYPE = "index"; - final String index; - final String docType; + @Nullable final String docType; + @Nullable final String index; @Nullable final String docId; @Nullable final String executionTimeField; @Nullable final TimeValue timeout; @Nullable final DateTimeZone dynamicNameTimeZone; - public IndexAction(String index, String docType, @Nullable String docId, + public IndexAction(@Nullable String index, @Nullable String docType, @Nullable String docId, @Nullable String executionTimeField, @Nullable TimeValue timeout, @Nullable DateTimeZone dynamicNameTimeZone) { this.index = index; @@ -89,8 +89,12 @@ public class IndexAction implements Action { @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); - builder.field(Field.INDEX.getPreferredName(), index); - builder.field(Field.DOC_TYPE.getPreferredName(), docType); + if (index != null) { + builder.field(Field.INDEX.getPreferredName(), index); + } + if (docType != null) { + builder.field(Field.DOC_TYPE.getPreferredName(), docType); + } if (docId != null) { builder.field(Field.DOC_ID.getPreferredName(), docId); } @@ -144,12 +148,7 @@ public class IndexAction implements Action { // Parser for human specified timeouts and 2.x compatibility timeout = WatcherDateTimeUtils.parseTimeValue(parser, Field.TIMEOUT_HUMAN.toString()); } else if (Field.DYNAMIC_NAME_TIMEZONE.match(currentFieldName)) { - if (token == XContentParser.Token.VALUE_STRING) { - dynamicNameTimeZone = DateTimeZone.forID(parser.text()); - } else { - throw new ElasticsearchParseException("could not parse [{}] action for watch [{}]. failed to parse [{}]. must be " + - "a string value (e.g. 'UTC' or '+01:00').", TYPE, watchId, currentFieldName); - } + dynamicNameTimeZone = DateTimeZone.forID(parser.text()); } else { throw new ElasticsearchParseException("could not parse [{}] action [{}/{}]. unexpected string field [{}]", TYPE, watchId, actionId, currentFieldName); @@ -160,16 +159,6 @@ public class IndexAction implements Action { } } - if (index == null) { - throw new ElasticsearchParseException("could not parse [{}] action [{}/{}]. missing required [{}] field", TYPE, watchId, - actionId, Field.INDEX.getPreferredName()); - } - - if (docType == null) { - throw new ElasticsearchParseException("could not parse [{}] action [{}/{}]. missing required [{}] field", TYPE, watchId, - actionId, Field.DOC_TYPE.getPreferredName()); - } - return new IndexAction(index, docType, docId, executionTimeField, timeout, dynamicNameTimeZone); } diff --git a/plugin/src/test/java/org/elasticsearch/xpack/watcher/actions/index/IndexActionTests.java b/plugin/src/test/java/org/elasticsearch/xpack/watcher/actions/index/IndexActionTests.java index bbcf979a19b..f158d44997d 100644 --- a/plugin/src/test/java/org/elasticsearch/xpack/watcher/actions/index/IndexActionTests.java +++ b/plugin/src/test/java/org/elasticsearch/xpack/watcher/actions/index/IndexActionTests.java @@ -5,27 +5,35 @@ */ package org.elasticsearch.xpack.watcher.actions.index; +import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchParseException; -import org.elasticsearch.action.search.SearchRequestBuilder; -import org.elasticsearch.action.search.SearchResponse; -import org.elasticsearch.action.support.WriteRequest; +import org.elasticsearch.action.DocWriteRequest; +import org.elasticsearch.action.bulk.BulkItemResponse; +import org.elasticsearch.action.bulk.BulkRequest; +import org.elasticsearch.action.bulk.BulkResponse; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.support.PlainActionFuture; +import org.elasticsearch.client.Client; import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.search.SearchHit; -import org.elasticsearch.search.aggregations.bucket.terms.Terms; -import org.elasticsearch.search.sort.SortOrder; -import org.elasticsearch.test.ESIntegTestCase; +import org.elasticsearch.index.Index; +import org.elasticsearch.index.shard.ShardId; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.xpack.watcher.actions.Action; import org.elasticsearch.xpack.watcher.actions.Action.Result.Status; import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext; -import org.elasticsearch.xpack.watcher.support.WatcherDateTimeUtils; import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource; import org.elasticsearch.xpack.watcher.test.WatcherTestUtils; import org.elasticsearch.xpack.watcher.watch.Payload; import org.joda.time.DateTime; +import org.junit.Before; +import org.mockito.ArgumentCaptor; import java.util.ArrayList; import java.util.Arrays; @@ -37,161 +45,36 @@ import static java.util.Collections.singletonMap; import static java.util.Collections.unmodifiableSet; import static org.elasticsearch.common.util.set.Sets.newHashSet; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; -import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; -import static org.elasticsearch.search.aggregations.AggregationBuilders.terms; -import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource; -import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.startsWith; import static org.joda.time.DateTimeZone.UTC; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; -public class IndexActionTests extends ESIntegTestCase { +public class IndexActionTests extends ESTestCase { - public void testIndexActionExecuteSingleDoc() throws Exception { - boolean customId = randomBoolean(); - boolean docIdAsParam = customId && randomBoolean(); - String docId = randomAlphaOfLength(5); - String timestampField = randomFrom("@timestamp", null); - boolean customTimestampField = timestampField != null; + private final Client client = mock(Client.class); - IndexAction action = new IndexAction("test-index", "test-type", docIdAsParam ? docId : null, timestampField, null, null); - ExecutableIndexAction executable = new ExecutableIndexAction(action, logger, client(), TimeValue.timeValueSeconds(30), - TimeValue.timeValueSeconds(30)); - DateTime executionTime = DateTime.now(UTC); - Payload payload; - - if (customId && docIdAsParam == false) { - // intentionally immutable because the other side needs to cut out _id - payload = new Payload.Simple("_doc", MapBuilder.newMapBuilder().put("foo", "bar").put("_id", docId).immutableMap()); - } else { - payload = randomBoolean() ? new Payload.Simple("foo", "bar") : new Payload.Simple("_doc", singletonMap("foo", "bar")); - } - - WatchExecutionContext ctx = WatcherTestUtils.mockExecutionContext("_id", executionTime, payload); - - Action.Result result = executable.execute("_id", ctx, ctx.payload()); - - assertThat(result.status(), equalTo(Status.SUCCESS)); - assertThat(result, instanceOf(IndexAction.Result.class)); - IndexAction.Result successResult = (IndexAction.Result) result; - XContentSource response = successResult.response(); - assertThat(response.getValue("created"), equalTo((Object)Boolean.TRUE)); - assertThat(response.getValue("version"), equalTo((Object) 1)); - assertThat(response.getValue("type").toString(), equalTo("test-type")); - assertThat(response.getValue("index").toString(), equalTo("test-index")); - - refresh(); //Manually refresh to make sure data is available - - SearchRequestBuilder searchRequestbuilder = client().prepareSearch("test-index") - .setTypes("test-type") - .setSource(searchSource().query(matchAllQuery())); - - if (customTimestampField) { - searchRequestbuilder.addAggregation(terms("timestamps").field(timestampField)); - } - - SearchResponse searchResponse = searchRequestbuilder.get(); - - assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L)); - SearchHit hit = searchResponse.getHits().getAt(0); - - if (customId) { - assertThat(hit.getId(), is(docId)); - } - - if (customTimestampField) { - assertThat(hit.getSourceAsMap().size(), is(2)); - assertThat(hit.getSourceAsMap(), hasEntry("foo", (Object) "bar")); - assertThat(hit.getSourceAsMap(), hasEntry(timestampField, (Object) WatcherDateTimeUtils.formatDate(executionTime))); - - Terms terms = searchResponse.getAggregations().get("timestamps"); - assertThat(terms, notNullValue()); - assertThat(terms.getBuckets(), hasSize(1)); - assertThat(terms.getBuckets().get(0).getKeyAsNumber().longValue(), is(executionTime.getMillis())); - assertThat(terms.getBuckets().get(0).getDocCount(), is(1L)); - } else { - assertThat(hit.getSourceAsMap().size(), is(1)); - assertThat(hit.getSourceAsMap(), hasEntry("foo", (Object) "bar")); - } - } - - public void testIndexActionExecuteMultiDoc() throws Exception { - String timestampField = randomFrom("@timestamp", null); - boolean customTimestampField = "@timestamp".equals(timestampField); - - assertAcked(prepareCreate("test-index") - .addMapping("test-type", "foo", "type=keyword")); - - List idList = Arrays.asList( - MapBuilder.newMapBuilder().put("foo", "bar").put("_id", "0").immutableMap(), - MapBuilder.newMapBuilder().put("foo", "bar1").put("_id", "1").map() - ); - - Object list = randomFrom( - new Map[] { singletonMap("foo", "bar"), singletonMap("foo", "bar1") }, - Arrays.asList(singletonMap("foo", "bar"), singletonMap("foo", "bar1")), - unmodifiableSet(newHashSet(singletonMap("foo", "bar"), singletonMap("foo", "bar1"))), - idList - ); - - boolean customId = list == idList; - - IndexAction action = new IndexAction("test-index", "test-type", null, timestampField, null, null); - ExecutableIndexAction executable = new ExecutableIndexAction(action, logger, client(), TimeValue.timeValueSeconds(30), - TimeValue.timeValueSeconds(30)); - DateTime executionTime = DateTime.now(UTC); - WatchExecutionContext ctx = WatcherTestUtils.mockExecutionContext("watch_id", executionTime, new Payload.Simple("_doc", list)); - - Action.Result result = executable.execute("watch_id", ctx, ctx.payload()); - - assertThat(result.status(), equalTo(Status.SUCCESS)); - assertThat(result, instanceOf(IndexAction.Result.class)); - IndexAction.Result successResult = (IndexAction.Result) result; - XContentSource response = successResult.response(); - assertThat(successResult.toString(), response.getValue("0.created"), equalTo((Object)Boolean.TRUE)); - assertThat(successResult.toString(), response.getValue("0.version"), equalTo((Object) 1)); - assertThat(successResult.toString(), response.getValue("0.type").toString(), equalTo("test-type")); - assertThat(successResult.toString(), response.getValue("0.index").toString(), equalTo("test-index")); - assertThat(successResult.toString(), response.getValue("1.created"), equalTo((Object)Boolean.TRUE)); - assertThat(successResult.toString(), response.getValue("1.version"), equalTo((Object) 1)); - assertThat(successResult.toString(), response.getValue("1.type").toString(), equalTo("test-type")); - assertThat(successResult.toString(), response.getValue("1.index").toString(), equalTo("test-index")); - - refresh(); //Manually refresh to make sure data is available - - SearchResponse searchResponse = client().prepareSearch("test-index") - .setTypes("test-type") - .setSource(searchSource().sort("foo", SortOrder.ASC) - .query(matchAllQuery())) - .get(); - - assertThat(searchResponse.getHits().getTotalHits(), equalTo(2L)); - final int fields = customTimestampField ? 2 : 1; - for (int i = 0; i < 2; ++i) { - final SearchHit hit = searchResponse.getHits().getAt(i); - final String value = "bar" + (i != 0 ? i : ""); - - assertThat(hit.getSourceAsMap().size(), is(fields)); - - if (customId) { - assertThat(hit.getId(), is(Integer.toString(i))); - } - if (customTimestampField) { - assertThat(hit.getSourceAsMap(), hasEntry(timestampField, (Object) WatcherDateTimeUtils.formatDate(executionTime))); - } - assertThat(hit.getSourceAsMap(), hasEntry("foo", (Object) value)); - } + @Before + public void setupClient() { + ThreadPool threadPool = mock(ThreadPool.class); + ThreadContext threadContext = new ThreadContext(Settings.EMPTY); + when(threadPool.getThreadContext()).thenReturn(threadContext); + when(client.threadPool()).thenReturn(threadPool); } public void testParser() throws Exception { String timestampField = randomBoolean() ? "@timestamp" : null; XContentBuilder builder = jsonBuilder(); builder.startObject(); - builder.field(IndexAction.Field.INDEX.getPreferredName(), "test-index"); + boolean includeIndex = randomBoolean(); + if (includeIndex) { + builder.field(IndexAction.Field.INDEX.getPreferredName(), "test-index"); + } builder.field(IndexAction.Field.DOC_TYPE.getPreferredName(), "test-type"); if (timestampField != null) { builder.field(IndexAction.Field.EXECUTION_TIME_FIELD.getPreferredName(), timestampField); @@ -201,14 +84,16 @@ public class IndexActionTests extends ESIntegTestCase { builder.field(IndexAction.Field.TIMEOUT.getPreferredName(), writeTimeout.millis()); } builder.endObject(); - IndexActionFactory actionParser = new IndexActionFactory(Settings.EMPTY, client()); + IndexActionFactory actionParser = new IndexActionFactory(Settings.EMPTY, client); XContentParser parser = createParser(builder); parser.nextToken(); ExecutableIndexAction executable = actionParser.parseExecutable(randomAlphaOfLength(5), randomAlphaOfLength(3), parser); assertThat(executable.action().docType, equalTo("test-type")); - assertThat(executable.action().index, equalTo("test-index")); + if (includeIndex) { + assertThat(executable.action().index, equalTo("test-index")); + } if (timestampField != null) { assertThat(executable.action().executionTimeField, equalTo(timestampField)); } @@ -216,63 +101,40 @@ public class IndexActionTests extends ESIntegTestCase { } public void testParserFailure() throws Exception { - XContentBuilder builder = jsonBuilder(); - boolean useIndex = randomBoolean(); - boolean useType = randomBoolean(); - builder.startObject(); - { - if (useIndex) { - builder.field(IndexAction.Field.INDEX.getPreferredName(), "test-index"); - } - if (useType) { - builder.field(IndexAction.Field.DOC_TYPE.getPreferredName(), "test-type"); - } - } - builder.endObject(); - IndexActionFactory actionParser = new IndexActionFactory(Settings.EMPTY, client()); - XContentParser parser = createParser(builder); - parser.nextToken(); - try { - actionParser.parseExecutable(randomAlphaOfLength(4), randomAlphaOfLength(5), parser); - if (!(useIndex && useType)) { - fail(); - } - } catch (ElasticsearchParseException iae) { - assertThat(useIndex && useType, equalTo(false)); - } + // wrong type for field + expectParseFailure(jsonBuilder() + .startObject() + .field(IndexAction.Field.DOC_TYPE.getPreferredName(), 1234) + .endObject()); + + expectParseFailure(jsonBuilder() + .startObject() + .field(IndexAction.Field.TIMEOUT.getPreferredName(), "1234") + .endObject()); + + // unknown field + expectParseFailure(jsonBuilder() + .startObject() + .field("unknown", "whatever") + .endObject()); + + expectParseFailure(jsonBuilder() + .startObject() + .field("unknown", 1234) + .endObject()); } - // https://github.com/elastic/x-pack/issues/4416 - public void testIndexingWithWrongMappingReturnsFailureResult() throws Exception { - // index a document to set the mapping of the foo field to a boolean - client().prepareIndex("test-index", "test-type", "_id").setSource("foo", true) - .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).get(); - - IndexAction action = new IndexAction("test-index", "test-type", null, "@timestamp", null, null); - ExecutableIndexAction executable = new ExecutableIndexAction(action, logger, client(), - TimeValue.timeValueSeconds(30), TimeValue.timeValueSeconds(30)); - - List> docs = new ArrayList<>(); - boolean addSuccessfulIndexedDoc = randomBoolean(); - if (addSuccessfulIndexedDoc) { - docs.add(Collections.singletonMap("foo", randomBoolean())); - } - docs.add(Collections.singletonMap("foo", Collections.singletonMap("foo", "bar"))); - Payload payload = new Payload.Simple(Collections.singletonMap("_doc", docs)); - - WatchExecutionContext ctx = WatcherTestUtils.mockExecutionContext("_id", DateTime.now(UTC), payload); - - Action.Result result = executable.execute("_id", ctx, payload); - if (addSuccessfulIndexedDoc) { - assertThat(result.status(), is(Status.PARTIAL_FAILURE)); - } else { - assertThat(result.status(), is(Status.FAILURE)); - } + private void expectParseFailure(XContentBuilder builder) throws Exception { + IndexActionFactory actionParser = new IndexActionFactory(Settings.EMPTY, client); + XContentParser parser = createParser(builder); + parser.nextToken(); + expectThrows(ElasticsearchParseException.class, () -> + actionParser.parseExecutable(randomAlphaOfLength(4), randomAlphaOfLength(5), parser)); } public void testUsingParameterIdWithBulkOrIdFieldThrowsIllegalState() { final IndexAction action = new IndexAction("test-index", "test-type", "123", null, null, null); - final ExecutableIndexAction executable = new ExecutableIndexAction(action, logger, client(), + final ExecutableIndexAction executable = new ExecutableIndexAction(action, logger, client, TimeValue.timeValueSeconds(30), TimeValue.timeValueSeconds(30)); final Map docWithId = MapBuilder.newMapBuilder().put("foo", "bar").put("_id", "0").immutableMap(); final DateTime executionTime = DateTime.now(UTC); @@ -301,4 +163,184 @@ public class IndexActionTests extends ESIntegTestCase { executable.execute("_id", ctx, ctx.payload()); }); } + + public void testThatIndexTypeIdDynamically() throws Exception { + boolean configureIndexDynamically = randomBoolean(); + boolean configureTypeDynamically = randomBoolean(); + boolean configureIdDynamically = (configureTypeDynamically == false && configureIndexDynamically == false) || randomBoolean(); + + MapBuilder builder = MapBuilder.newMapBuilder().put("foo", "bar"); + if (configureIdDynamically) { + builder.put("_id", "my_dynamic_id"); + } + if (configureTypeDynamically) { + builder.put("_type", "my_dynamic_type"); + } + if (configureIndexDynamically) { + builder.put("_index", "my_dynamic_index"); + } + + final IndexAction action = new IndexAction(configureIndexDynamically ? null : "my_index", + configureTypeDynamically ? null : "my_type", + configureIdDynamically ? null : "my_id", + null, null, null); + final ExecutableIndexAction executable = new ExecutableIndexAction(action, logger, client, + TimeValue.timeValueSeconds(30), TimeValue.timeValueSeconds(30)); + + final WatchExecutionContext ctx = WatcherTestUtils.mockExecutionContext("_id", new Payload.Simple(builder.immutableMap())); + + ArgumentCaptor captor = ArgumentCaptor.forClass(IndexRequest.class); + PlainActionFuture listener = PlainActionFuture.newFuture(); + listener.onResponse(new IndexResponse(new ShardId(new Index("foo", "bar"), 0), "whatever", "whatever", 1, 1, 1, true)); + when(client.index(captor.capture())).thenReturn(listener); + Action.Result result = executable.execute("_id", ctx, ctx.payload()); + + assertThat(result.status(), is(Status.SUCCESS)); + assertThat(captor.getAllValues(), hasSize(1)); + + assertThat(captor.getValue().index(), is(configureIndexDynamically ? "my_dynamic_index" : "my_index")); + assertThat(captor.getValue().type(), is(configureTypeDynamically ? "my_dynamic_type" : "my_type")); + assertThat(captor.getValue().id(), is(configureIdDynamically ? "my_dynamic_id" : "my_id")); + } + + public void testThatIndexActionCanBeConfiguredWithDynamicIndexNameAndBulk() throws Exception { + final IndexAction action = new IndexAction(null, "my-type", null, null, null, null); + final ExecutableIndexAction executable = new ExecutableIndexAction(action, logger, client, + TimeValue.timeValueSeconds(30), TimeValue.timeValueSeconds(30)); + + final Map docWithIndex = MapBuilder.newMapBuilder().put("foo", "bar") + .put("_index", "my-index").immutableMap(); + final Map docWithOtherIndex = MapBuilder.newMapBuilder().put("foo", "bar") + .put("_index", "my-other-index").immutableMap(); + final WatchExecutionContext ctx = WatcherTestUtils.mockExecutionContext("_id", + new Payload.Simple("_doc", Arrays.asList(docWithIndex, docWithOtherIndex))); + + ArgumentCaptor captor = ArgumentCaptor.forClass(BulkRequest.class); + PlainActionFuture listener = PlainActionFuture.newFuture(); + IndexResponse indexResponse = new IndexResponse(new ShardId(new Index("foo", "bar"), 0), "whatever", "whatever", 1, 1, 1, true); + BulkItemResponse response = new BulkItemResponse(0, DocWriteRequest.OpType.INDEX, indexResponse); + BulkResponse bulkResponse = new BulkResponse(new BulkItemResponse[]{response}, 1); + listener.onResponse(bulkResponse); + when(client.bulk(captor.capture())).thenReturn(listener); + Action.Result result = executable.execute("_id", ctx, ctx.payload()); + + assertThat(result.status(), is(Status.SUCCESS)); + assertThat(captor.getAllValues(), hasSize(1)); + assertThat(captor.getValue().requests(), hasSize(2)); + assertThat(captor.getValue().requests().get(0).type(), is("my-type")); + assertThat(captor.getValue().requests().get(0).index(), is("my-index")); + assertThat(captor.getValue().requests().get(1).type(), is("my-type")); + assertThat(captor.getValue().requests().get(1).index(), is("my-other-index")); + } + + public void testConfigureIndexInMapAndAction() { + String fieldName = randomFrom("_index", "_type"); + final IndexAction action = new IndexAction(fieldName.equals("_index") ? "my_index" : null, + fieldName.equals("_type") ? "my_type" : null, + null,null, null, null); + final ExecutableIndexAction executable = new ExecutableIndexAction(action, logger, client, + TimeValue.timeValueSeconds(30), TimeValue.timeValueSeconds(30)); + + final Map docWithIndex = MapBuilder.newMapBuilder().put("foo", "bar") + .put(fieldName, "my-value").immutableMap(); + final WatchExecutionContext ctx = WatcherTestUtils.mockExecutionContext("_id", + new Payload.Simple("_doc", Collections.singletonList(docWithIndex))); + + IllegalStateException e = expectThrows(IllegalStateException.class, () -> executable.execute("_id", ctx, ctx.payload())); + assertThat(e.getMessage(), startsWith("could not execute action [_id] of watch [_id]. [ctx.payload." + + fieldName + "] or [ctx.payload._doc." + fieldName + "]")); + } + + public void testIndexActionExecuteSingleDoc() throws Exception { + boolean customId = randomBoolean(); + boolean docIdAsParam = customId && randomBoolean(); + String docId = randomAlphaOfLength(5); + String timestampField = randomFrom("@timestamp", null); + + IndexAction action = new IndexAction("test-index", "test-type", docIdAsParam ? docId : null, timestampField, null, null); + ExecutableIndexAction executable = new ExecutableIndexAction(action, logger, client, TimeValue.timeValueSeconds(30), + TimeValue.timeValueSeconds(30)); + DateTime executionTime = DateTime.now(UTC); + Payload payload; + + if (customId && docIdAsParam == false) { + // intentionally immutable because the other side needs to cut out _id + payload = new Payload.Simple("_doc", MapBuilder.newMapBuilder().put("foo", "bar").put("_id", docId).immutableMap()); + } else { + payload = randomBoolean() ? new Payload.Simple("foo", "bar") : new Payload.Simple("_doc", singletonMap("foo", "bar")); + } + + WatchExecutionContext ctx = WatcherTestUtils.mockExecutionContext("_id", executionTime, payload); + + ArgumentCaptor captor = ArgumentCaptor.forClass(IndexRequest.class); + PlainActionFuture listener = PlainActionFuture.newFuture(); + listener.onResponse(new IndexResponse(new ShardId(new Index("test-index", "uuid"), 0), "test-type", docId, 1, 1, 1, true)); + when(client.index(captor.capture())).thenReturn(listener); + + Action.Result result = executable.execute("_id", ctx, ctx.payload()); + + assertThat(result.status(), equalTo(Status.SUCCESS)); + assertThat(result, instanceOf(IndexAction.Result.class)); + IndexAction.Result successResult = (IndexAction.Result) result; + XContentSource response = successResult.response(); + assertThat(response.getValue("created"), equalTo((Object)Boolean.TRUE)); + assertThat(response.getValue("version"), equalTo((Object) 1)); + assertThat(response.getValue("type").toString(), equalTo("test-type")); + assertThat(response.getValue("index").toString(), equalTo("test-index")); + + assertThat(captor.getAllValues(), hasSize(1)); + IndexRequest indexRequest = captor.getValue(); + assertThat(indexRequest.sourceAsMap(), is(hasEntry("foo", "bar"))); + if (customId) { + assertThat(indexRequest.id(), is(docId)); + } + + if (timestampField != null) { + assertThat(indexRequest.sourceAsMap().keySet(), is(hasSize(2))); + assertThat(indexRequest.sourceAsMap(), hasEntry(timestampField, executionTime.toString())); + } else { + assertThat(indexRequest.sourceAsMap().keySet(), is(hasSize(1))); + } + } + + public void testFailureResult() throws Exception { + IndexAction action = new IndexAction("test-index", "test-type", null, "@timestamp", null, null); + ExecutableIndexAction executable = new ExecutableIndexAction(action, logger, client, + TimeValue.timeValueSeconds(30), TimeValue.timeValueSeconds(30)); + + // should the result resemble a failure or a partial failure + boolean isPartialFailure = randomBoolean(); + + List> docs = new ArrayList<>(); + docs.add(Collections.singletonMap("foo", Collections.singletonMap("foo", "bar"))); + docs.add(Collections.singletonMap("foo", Collections.singletonMap("foo", "bar"))); + Payload payload = new Payload.Simple(Collections.singletonMap("_doc", docs)); + + WatchExecutionContext ctx = WatcherTestUtils.mockExecutionContext("_id", DateTime.now(UTC), payload); + + ArgumentCaptor captor = ArgumentCaptor.forClass(BulkRequest.class); + PlainActionFuture listener = PlainActionFuture.newFuture(); + BulkItemResponse.Failure failure = new BulkItemResponse.Failure("test-index", "test-type", "anything", + new ElasticsearchException("anything")); + BulkItemResponse firstResponse = new BulkItemResponse(0, DocWriteRequest.OpType.INDEX, failure); + BulkItemResponse secondResponse; + if (isPartialFailure) { + ShardId shardId = new ShardId(new Index("foo", "bar"), 0); + IndexResponse indexResponse = new IndexResponse(shardId, "whatever", "whatever", 1, 1, 1, true); + secondResponse = new BulkItemResponse(1, DocWriteRequest.OpType.INDEX, indexResponse); + } else { + secondResponse = new BulkItemResponse(1, DocWriteRequest.OpType.INDEX, failure); + } + BulkResponse bulkResponse = new BulkResponse(new BulkItemResponse[]{firstResponse, secondResponse}, 1); + listener.onResponse(bulkResponse); + when(client.bulk(captor.capture())).thenReturn(listener); + Action.Result result = executable.execute("_id", ctx, payload); + + if (isPartialFailure) { + assertThat(result.status(), is(Status.PARTIAL_FAILURE)); + } else { + assertThat(result.status(), is(Status.FAILURE)); + } + } + } From d5e03f9bfff048cab85055d75b612404d12b9a23 Mon Sep 17 00:00:00 2001 From: lcawley Date: Fri, 15 Dec 2017 11:05:20 -0800 Subject: [PATCH 07/12] [DOCS] Fixed troubleshooting titles Original commit: elastic/x-pack-elasticsearch@4338580de6b46caf8c68d8e36c6d8bc77fb914f2 --- docs/en/ml/troubleshooting.asciidoc | 5 ++++- docs/en/security/troubleshooting.asciidoc | 3 +++ docs/en/watcher/troubleshooting.asciidoc | 5 ++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/en/ml/troubleshooting.asciidoc b/docs/en/ml/troubleshooting.asciidoc index 2ffca1bd7e5..f8070a44b19 100644 --- a/docs/en/ml/troubleshooting.asciidoc +++ b/docs/en/ml/troubleshooting.asciidoc @@ -1,5 +1,8 @@ [[ml-troubleshooting]] == {xpackml} Troubleshooting +++++ +{xpackml} +++++ Use the information in this section to troubleshoot common problems and find answers for frequently asked questions. @@ -52,7 +55,7 @@ object mapping [field_name] with an object mapping [field_name]`. This issue typically occurs when two or more jobs store their results in the same index and the results contain fields with the same name but different -data types or different `fields` settings. +data types or different `fields` settings. By default, {ml} results are stored in the `.ml-anomalies-shared` index in {es}. To resolve this issue, click *Advanced > Use dedicated index* when you create diff --git a/docs/en/security/troubleshooting.asciidoc b/docs/en/security/troubleshooting.asciidoc index 64ca7522039..c4100ab8cac 100644 --- a/docs/en/security/troubleshooting.asciidoc +++ b/docs/en/security/troubleshooting.asciidoc @@ -1,5 +1,8 @@ [[security-troubleshooting]] == {security} Troubleshooting +++++ +{security} +++++ Use the information in this section to troubleshoot common problems and find answers for frequently asked questions. diff --git a/docs/en/watcher/troubleshooting.asciidoc b/docs/en/watcher/troubleshooting.asciidoc index 3319a1db93d..8b793142ecc 100644 --- a/docs/en/watcher/troubleshooting.asciidoc +++ b/docs/en/watcher/troubleshooting.asciidoc @@ -1,5 +1,8 @@ [[watcher-troubleshooting]] -== {watcher} Troubleshooting +== {xpack} {watcher} Troubleshooting +++++ +{xpack} {watcher} +++++ [float] === Dynamic Mapping Error When Trying to Add a Watch From cd245c8e86b5ab099ff07736a4cfae46f7447a2c Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Fri, 15 Dec 2017 11:19:11 -0800 Subject: [PATCH 08/12] [DOCS] Added xpack.ml.node_concurrent_job_allocations setting (elastic/x-pack-elasticsearch#3327) * [DOCS] Added concurrent ML job setting * [DOCS] Re-ordered ML settings * [DOCS] Clarified concurrent job allocation setting Original commit: elastic/x-pack-elasticsearch@cb2d50133328a72cb5bedf1115f695e2fe8a603b --- docs/en/settings/ml-settings.asciidoc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/en/settings/ml-settings.asciidoc b/docs/en/settings/ml-settings.asciidoc index 318d1857bdc..ff5ec6f205e 100644 --- a/docs/en/settings/ml-settings.asciidoc +++ b/docs/en/settings/ml-settings.asciidoc @@ -56,3 +56,9 @@ this node. If you try to create a job with a `model_memory_limit` property value that is greater than this setting value, an error occurs. Existing jobs are not affected when you update this setting. For more information about the `model_memory_limit` property, see <>. + +`xpack.ml.node_concurrent_job_allocations`:: +The maximum number of jobs that can concurrently be in the `opening` state on +each node. Typically, jobs spend a small amount of time in this state before +they move to `open` state. Jobs that must restore large models when they are +opening spend more time in the `opening` state. Defaults to `2`. From 02129beec492ce9e82001e317bc4b17ab1e6f8e7 Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Fri, 15 Dec 2017 15:05:21 -0800 Subject: [PATCH 09/12] [DOCS] Reformatted machine learning overview (elastic/x-pack-elasticsearch#3346) * [DOCS] Reformatted machine learning overview * [DOCS] Added intro ML screenshot Original commit: elastic/x-pack-elasticsearch@b6189000e0ceeeb50e38d00199ab61f6f51a87ec --- docs/en/ml/analyzing.asciidoc | 29 +++++++++++++++++++++++ docs/en/ml/images/ml-gs-job-analysis.jpg | Bin 0 -> 93755 bytes docs/en/ml/index.asciidoc | 28 +++++++--------------- docs/en/ml/overview.asciidoc | 10 +++++++- 4 files changed, 47 insertions(+), 20 deletions(-) create mode 100644 docs/en/ml/analyzing.asciidoc create mode 100644 docs/en/ml/images/ml-gs-job-analysis.jpg diff --git a/docs/en/ml/analyzing.asciidoc b/docs/en/ml/analyzing.asciidoc new file mode 100644 index 00000000000..d8b6640f2c8 --- /dev/null +++ b/docs/en/ml/analyzing.asciidoc @@ -0,0 +1,29 @@ +[float] +[[ml-analyzing]] +=== Analyzing the Past and Present + +The {xpackml} features automate the analysis of time-series data by creating +accurate baselines of normal behavior in the data and identifying anomalous +patterns in that data. You can submit your data for analysis in batches or +continuously in real-time {dfeeds}. + +Using proprietary {ml} algorithms, the following circumstances are detected, +scored, and linked with statistically significant influencers in the data: + +* Anomalies related to temporal deviations in values, counts, or frequencies +* Statistical rarity +* Unusual behaviors for a member of a population + +Automated periodicity detection and quick adaptation to changing data ensure +that you don’t need to specify algorithms, models, or other data science-related +configurations in order to get the benefits of {ml}. + +You can view the {ml} results in {kib} where, for example, charts illustrate the +actual data values, the bounds for the expected values, and the anomalies that +occur outside these bounds. + +[role="screenshot"] +image::images/ml-gs-job-analysis.jpg["Example screenshot from the Machine Learning Single Metric Viewer in Kibana"] + +For a more detailed walk-through of {xpackml} features, see +<>. diff --git a/docs/en/ml/images/ml-gs-job-analysis.jpg b/docs/en/ml/images/ml-gs-job-analysis.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7f80ff9726a1eaa49c3f1aee04a374c783a1d466 GIT binary patch literal 93755 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 literal 0 HcmV?d00001 diff --git a/docs/en/ml/index.asciidoc b/docs/en/ml/index.asciidoc index 3f6c4f1ba7f..c36f77ca812 100644 --- a/docs/en/ml/index.asciidoc +++ b/docs/en/ml/index.asciidoc @@ -3,28 +3,18 @@ [partintro] -- -The {xpackml} features automate the analysis of time-series data by creating -accurate baselines of normal behaviors in the data and identifying anomalous -patterns in that data. - -Using proprietary {ml} algorithms, the following circumstances are detected, -scored, and linked with statistically significant influencers in the data: - -* Anomalies related to temporal deviations in values, counts, or frequencies -* Statistical rarity -* Unusual behaviors for a member of a population - -Automated periodicity detection and quick adaptation to changing data ensure -that you don’t need to specify algorithms, models, or other data science-related -configurations in order to get the benefits of {ml}. - -[float] -[[ml-intro]] -== Integration with the Elastic Stack - Machine learning is tightly integrated with the Elastic Stack. Data is pulled from {es} for analysis and anomaly results are displayed in {kib} dashboards. +* <> +* <> +* <> +* <> +* <> +* <> +* <> + + -- include::overview.asciidoc[] diff --git a/docs/en/ml/overview.asciidoc b/docs/en/ml/overview.asciidoc index 404697320c4..df396615342 100644 --- a/docs/en/ml/overview.asciidoc +++ b/docs/en/ml/overview.asciidoc @@ -1,6 +1,14 @@ -[[ml-concepts]] +[[ml-overview]] == Overview +include::analyzing.asciidoc[] + +[[ml-concepts]] +=== Basic Machine Learning Terms +++++ +Basic Terms +++++ + There are a few concepts that are core to {ml} in {xpack}. Understanding these concepts from the outset will tremendously help ease the learning process. From 01f531864299cf3f99de9252ffec4115a98ba155 Mon Sep 17 00:00:00 2001 From: Chris Earle Date: Fri, 15 Dec 2017 18:32:34 -0500 Subject: [PATCH 10/12] [Watcher] Use index.auto_expand_replicas: 0-1 (elastic/x-pack-elasticsearch#3284) This changes the default behavior of .watch* indices to be green on one-node clusters, instead of constantly yellow. Original commit: elastic/x-pack-elasticsearch@cdaee7cd72ad4b542ab7031121bd50f04be6a143 --- plugin/src/main/resources/watch-history.json | 2 ++ plugin/src/main/resources/watches.json | 2 ++ 2 files changed, 4 insertions(+) diff --git a/plugin/src/main/resources/watch-history.json b/plugin/src/main/resources/watch-history.json index af4b221b93e..a26305b3554 100644 --- a/plugin/src/main/resources/watch-history.json +++ b/plugin/src/main/resources/watch-history.json @@ -4,6 +4,8 @@ "settings": { "xpack.watcher.template.version": "${xpack.watcher.template.version}", "index.number_of_shards": 1, + "index.number_of_replicas": 0, + "index.auto_expand_replicas": "0-1", "index.format": 6 }, "mappings": { diff --git a/plugin/src/main/resources/watches.json b/plugin/src/main/resources/watches.json index 278c6275e69..ad744c44f11 100644 --- a/plugin/src/main/resources/watches.json +++ b/plugin/src/main/resources/watches.json @@ -3,6 +3,8 @@ "order": 2147483647, "settings": { "index.number_of_shards": 1, + "index.number_of_replicas": 0, + "index.auto_expand_replicas": "0-1", "index.format": 6, "index.priority": 800 }, From d97bfac8fcc0c5dfa37ad75b7956b80619d5bf56 Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Sun, 17 Dec 2017 11:24:31 -0500 Subject: [PATCH 11/12] Fix elasticsearch-cli dependency The API JAR POM picks up the wrong artifact name for the :core:cli dependency, using the project name instead of the archive base name. This commit fixes this issue by explicitly referring to the artifact as a runtime dependency. With this change, the correct artifact name is used in the API JAR POM. Relates elastic/x-pack-elasticsearch#3336 Original commit: elastic/x-pack-elasticsearch@68026168dac69c6d41634f0e21f72d5c85bf0bc2 --- plugin/build.gradle | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugin/build.gradle b/plugin/build.gradle index 47054277708..4e7cef70f23 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -55,8 +55,11 @@ configurations { } dependencies { - // CLI deps - compile project(path: ':core:cli', configuration: 'runtime') + /* + * There appears to be a bug in maven-publish for project dependencies that set an archivesBaseName so this needs to be a runtime artifact + * dependency. + */ + runtime "org.elasticsearch:elasticsearch-cli:${version}" // security deps compile project(path: ':modules:transport-netty4', configuration: 'runtime') From c92a21651771d09520f4ab797e2cd5e67c06489b Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Sun, 17 Dec 2017 11:54:30 -0500 Subject: [PATCH 12/12] Revert "Fix elasticsearch-cli dependency" This reverts commit elastic/x-pack-elasticsearch@68026168dac69c6d41634f0e21f72d5c85bf0bc2. Relates elastic/x-pack-elasticsearch#3349 Original commit: elastic/x-pack-elasticsearch@2c345ee5a498d464c0dbb96ef07acddfb40036ab --- plugin/build.gradle | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/plugin/build.gradle b/plugin/build.gradle index 4e7cef70f23..47054277708 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -55,11 +55,8 @@ configurations { } dependencies { - /* - * There appears to be a bug in maven-publish for project dependencies that set an archivesBaseName so this needs to be a runtime artifact - * dependency. - */ - runtime "org.elasticsearch:elasticsearch-cli:${version}" + // CLI deps + compile project(path: ':core:cli', configuration: 'runtime') // security deps compile project(path: ':modules:transport-netty4', configuration: 'runtime')