listener) {
@@ -492,6 +494,47 @@ public void putDatafeedAsync(PutDatafeedRequest request, RequestOptions options,
Collections.emptySet());
}
+ /**
+ * Gets one or more Machine Learning datafeed configuration info.
+ *
+ *
+ * For additional info
+ * see ML GET datafeed documentation
+ *
+ * @param request {@link GetDatafeedRequest} Request containing a list of datafeedId(s) and additional options
+ * @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
+ * @return {@link GetDatafeedResponse} response object containing
+ * the {@link org.elasticsearch.client.ml.datafeed.DatafeedConfig} objects and the number of jobs found
+ * @throws IOException when there is a serialization issue sending the request or receiving the response
+ */
+ public GetDatafeedResponse getDatafeed(GetDatafeedRequest request, RequestOptions options) throws IOException {
+ return restHighLevelClient.performRequestAndParseEntity(request,
+ MLRequestConverters::getDatafeed,
+ options,
+ GetDatafeedResponse::fromXContent,
+ Collections.emptySet());
+ }
+
+ /**
+ * Gets one or more Machine Learning datafeed configuration info, asynchronously.
+ *
+ *
+ * For additional info
+ * see ML GET datafeed documentation
+ *
+ * @param request {@link GetDatafeedRequest} Request containing a list of datafeedId(s) and additional options
+ * @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
+ * @param listener Listener to be notified with {@link GetDatafeedResponse} upon request completion
+ */
+ public void getDatafeedAsync(GetDatafeedRequest request, RequestOptions options, ActionListener listener) {
+ restHighLevelClient.performRequestAsyncAndParseEntity(request,
+ MLRequestConverters::getDatafeed,
+ options,
+ GetDatafeedResponse::fromXContent,
+ listener,
+ Collections.emptySet());
+ }
+
/**
* Deletes the given Machine Learning Datafeed
*
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/CloseJobRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/CloseJobRequest.java
index 19f3df8e4320f..aa6b4fe6c9a0d 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/CloseJobRequest.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/CloseJobRequest.java
@@ -136,9 +136,9 @@ public Boolean isAllowNoJobs() {
/**
* Whether to ignore if a wildcard expression matches no jobs.
*
- * This includes `_all` string or when no jobs have been specified
+ * This includes {@code _all} string or when no jobs have been specified
*
- * @param allowNoJobs When {@code true} ignore if wildcard or `_all` matches no jobs. Defaults to {@code true}
+ * @param allowNoJobs When {@code true} ignore if wildcard or {@code _all} matches no jobs. Defaults to {@code true}
*/
public void setAllowNoJobs(boolean allowNoJobs) {
this.allowNoJobs = allowNoJobs;
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/DeleteForecastRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/DeleteForecastRequest.java
index f7c8a6c0733f8..f1d87fa45d6e7 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/DeleteForecastRequest.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/DeleteForecastRequest.java
@@ -109,7 +109,7 @@ public Boolean isAllowNoForecasts() {
}
/**
- * Sets the `allow_no_forecasts` field.
+ * Sets the value of "allow_no_forecasts".
*
* @param allowNoForecasts when {@code true} no error is thrown when {@link DeleteForecastRequest#ALL} does not find any forecasts
*/
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetDatafeedRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetDatafeedRequest.java
new file mode 100644
index 0000000000000..d9750d9616ddf
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetDatafeedRequest.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.elasticsearch.client.ml;
+
+import org.elasticsearch.action.ActionRequest;
+import org.elasticsearch.action.ActionRequestValidationException;
+import org.elasticsearch.client.ml.datafeed.DatafeedConfig;
+import org.elasticsearch.common.ParseField;
+import org.elasticsearch.common.xcontent.ConstructingObjectParser;
+import org.elasticsearch.common.xcontent.ToXContentObject;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Request object to get {@link DatafeedConfig} objects with the matching {@code datafeedId}s.
+ *
+ * {@code _all} explicitly gets all the datafeeds in the cluster
+ * An empty request (no {@code datafeedId}s) implicitly gets all the datafeeds in the cluster
+ */
+public class GetDatafeedRequest extends ActionRequest implements ToXContentObject {
+
+ public static final ParseField DATAFEED_IDS = new ParseField("datafeed_ids");
+ public static final ParseField ALLOW_NO_DATAFEEDS = new ParseField("allow_no_datafeeds");
+
+ private static final String ALL_DATAFEEDS = "_all";
+ private final List datafeedIds;
+ private Boolean allowNoDatafeeds;
+
+ @SuppressWarnings("unchecked")
+ public static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(
+ "get_datafeed_request",
+ true, a -> new GetDatafeedRequest(a[0] == null ? new ArrayList<>() : (List) a[0]));
+
+ static {
+ PARSER.declareStringArray(ConstructingObjectParser.optionalConstructorArg(), DATAFEED_IDS);
+ PARSER.declareBoolean(GetDatafeedRequest::setAllowNoDatafeeds, ALLOW_NO_DATAFEEDS);
+ }
+
+ /**
+ * Helper method to create a query that will get ALL datafeeds
+ * @return new {@link GetDatafeedRequest} object searching for the datafeedId "_all"
+ */
+ public static GetDatafeedRequest getAllDatafeedsRequest() {
+ return new GetDatafeedRequest(ALL_DATAFEEDS);
+ }
+
+ /**
+ * Get the specified {@link DatafeedConfig} configurations via their unique datafeedIds
+ * @param datafeedIds must not contain any null values
+ */
+ public GetDatafeedRequest(String... datafeedIds) {
+ this(Arrays.asList(datafeedIds));
+ }
+
+ GetDatafeedRequest(List datafeedIds) {
+ if (datafeedIds.stream().anyMatch(Objects::isNull)) {
+ throw new NullPointerException("datafeedIds must not contain null values");
+ }
+ this.datafeedIds = new ArrayList<>(datafeedIds);
+ }
+
+ /**
+ * All the datafeedIds for which to get configuration information
+ */
+ public List getDatafeedIds() {
+ return datafeedIds;
+ }
+
+ /**
+ * Whether to ignore if a wildcard expression matches no datafeeds.
+ *
+ * @param allowNoDatafeeds If this is {@code false}, then an error is returned when a wildcard (or {@code _all})
+ * does not match any datafeeds
+ */
+ public void setAllowNoDatafeeds(boolean allowNoDatafeeds) {
+ this.allowNoDatafeeds = allowNoDatafeeds;
+ }
+
+ public Boolean isAllowNoDatafeeds() {
+ return allowNoDatafeeds;
+ }
+
+ @Override
+ public ActionRequestValidationException validate() {
+ return null;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(datafeedIds, allowNoDatafeeds);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+
+ if (other == null || other.getClass() != getClass()) {
+ return false;
+ }
+
+ GetDatafeedRequest that = (GetDatafeedRequest) other;
+ return Objects.equals(datafeedIds, that.datafeedIds) &&
+ Objects.equals(allowNoDatafeeds, that.allowNoDatafeeds);
+ }
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+ builder.startObject();
+
+ if (datafeedIds.isEmpty() == false) {
+ builder.field(DATAFEED_IDS.getPreferredName(), datafeedIds);
+ }
+
+ if (allowNoDatafeeds != null) {
+ builder.field(ALLOW_NO_DATAFEEDS.getPreferredName(), allowNoDatafeeds);
+ }
+
+ builder.endObject();
+ return builder;
+ }
+}
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetDatafeedResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetDatafeedResponse.java
new file mode 100644
index 0000000000000..0aadd7a576662
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetDatafeedResponse.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.elasticsearch.client.ml;
+
+import org.elasticsearch.client.ml.datafeed.DatafeedConfig;
+import org.elasticsearch.common.ParseField;
+import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.xcontent.ConstructingObjectParser;
+import org.elasticsearch.common.xcontent.XContentParser;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
+
+/**
+ * Contains a {@link List} of the found {@link DatafeedConfig} objects and the total count found
+ */
+public class GetDatafeedResponse extends AbstractResultResponse {
+
+ public static final ParseField RESULTS_FIELD = new ParseField("datafeeds");
+
+ @SuppressWarnings("unchecked")
+ public static final ConstructingObjectParser PARSER =
+ new ConstructingObjectParser<>("get_datafeed_response", true,
+ a -> new GetDatafeedResponse((List) a[0], (long) a[1]));
+
+ static {
+ PARSER.declareObjectArray(constructorArg(), DatafeedConfig.PARSER, RESULTS_FIELD);
+ PARSER.declareLong(constructorArg(), AbstractResultResponse.COUNT);
+ }
+
+ GetDatafeedResponse(List datafeedBuilders, long count) {
+ super(RESULTS_FIELD, datafeedBuilders.stream().map(DatafeedConfig.Builder::build).collect(Collectors.toList()), count);
+ }
+
+ /**
+ * The collection of {@link DatafeedConfig} objects found in the query
+ */
+ public List datafeeds() {
+ return results;
+ }
+
+ public static GetDatafeedResponse fromXContent(XContentParser parser) throws IOException {
+ return PARSER.parse(parser, null);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(results, count);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+
+ GetDatafeedResponse other = (GetDatafeedResponse) obj;
+ return Objects.equals(results, other.results) && count == other.count;
+ }
+
+ @Override
+ public final String toString() {
+ return Strings.toString(this);
+ }
+}
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetJobRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetJobRequest.java
index 3de7037e5c8f3..46153061e2803 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetJobRequest.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetJobRequest.java
@@ -33,11 +33,11 @@
import java.util.Objects;
/**
- * Request object to get {@link Job} objects with the matching `jobId`s or
- * `groupName`s.
+ * Request object to get {@link Job} objects with the matching {@code jobId}s or
+ * {@code groupName}s.
*
- * `_all` explicitly gets all the jobs in the cluster
- * An empty request (no `jobId`s) implicitly gets all the jobs in the cluster
+ * {@code _all} explicitly gets all the jobs in the cluster
+ * An empty request (no {@code jobId}s) implicitly gets all the jobs in the cluster
*/
public class GetJobRequest extends ActionRequest implements ToXContentObject {
@@ -91,7 +91,7 @@ public List getJobIds() {
/**
* Whether to ignore if a wildcard expression matches no jobs.
*
- * @param allowNoJobs If this is {@code false}, then an error is returned when a wildcard (or `_all`) does not match any jobs
+ * @param allowNoJobs If this is {@code false}, then an error is returned when a wildcard (or {@code _all}) does not match any jobs
*/
public void setAllowNoJobs(boolean allowNoJobs) {
this.allowNoJobs = allowNoJobs;
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetJobStatsRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetJobStatsRequest.java
index d8eb350755dcb..fc3af822163a1 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetJobStatsRequest.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetJobStatsRequest.java
@@ -38,8 +38,8 @@
/**
* Request object to get {@link org.elasticsearch.client.ml.job.stats.JobStats} by their respective jobIds
*
- * `_all` explicitly gets all the jobs' statistics in the cluster
- * An empty request (no `jobId`s) implicitly gets all the jobs' statistics in the cluster
+ * {@code _all} explicitly gets all the jobs' statistics in the cluster
+ * An empty request (no {@code jobId}s) implicitly gets all the jobs' statistics in the cluster
*/
public class GetJobStatsRequest extends ActionRequest implements ToXContentObject {
@@ -100,9 +100,9 @@ public Boolean isAllowNoJobs() {
/**
* Whether to ignore if a wildcard expression matches no jobs.
*
- * This includes `_all` string or when no jobs have been specified
+ * This includes {@code _all} string or when no jobs have been specified
*
- * @param allowNoJobs When {@code true} ignore if wildcard or `_all` matches no jobs. Defaults to {@code true}
+ * @param allowNoJobs When {@code true} ignore if wildcard or {@code _all} matches no jobs. Defaults to {@code true}
*/
public void setAllowNoJobs(boolean allowNoJobs) {
this.allowNoJobs = allowNoJobs;
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetOverallBucketsRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetOverallBucketsRequest.java
index 97bde11d8c6cd..490bdd4fbaeb3 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetOverallBucketsRequest.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetOverallBucketsRequest.java
@@ -109,7 +109,7 @@ public Integer getTopN() {
}
/**
- * Sets the value of `top_n`.
+ * Sets the value of "top_n".
* @param topN The number of top job bucket scores to be used in the overall_score calculation. Defaults to 1.
*/
public void setTopN(Integer topN) {
@@ -121,7 +121,7 @@ public TimeValue getBucketSpan() {
}
/**
- * Sets the value of `bucket_span`.
+ * Sets the value of "bucket_span".
* @param bucketSpan The span of the overall buckets. Must be greater or equal to the largest job’s bucket_span.
* Defaults to the largest job’s bucket_span.
*/
@@ -197,7 +197,7 @@ public void setAllowNoJobs(boolean allowNoJobs) {
/**
* Whether to ignore if a wildcard expression matches no jobs.
*
- * If this is `false`, then an error is returned when a wildcard (or `_all`) does not match any jobs
+ * If this is {@code false}, then an error is returned when a wildcard (or {@code _all}) does not match any jobs
*/
public Boolean isAllowNoJobs() {
return allowNoJobs;
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/PostDataRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/PostDataRequest.java
index e84ff878437aa..c8e043cc1e569 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/PostDataRequest.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/PostDataRequest.java
@@ -40,7 +40,7 @@
import java.util.Objects;
/**
- * POJO for posting data to a Machine Learning job
+ * Request to post data to a Machine Learning job
*/
public class PostDataRequest extends ActionRequest implements ToXContentObject {
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/MLRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/MLRequestConvertersTests.java
index 547bc2e9a934f..b363e633657b9 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/MLRequestConvertersTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/MLRequestConvertersTests.java
@@ -31,6 +31,7 @@
import org.elasticsearch.client.ml.ForecastJobRequest;
import org.elasticsearch.client.ml.GetBucketsRequest;
import org.elasticsearch.client.ml.GetCategoriesRequest;
+import org.elasticsearch.client.ml.GetDatafeedRequest;
import org.elasticsearch.client.ml.GetInfluencersRequest;
import org.elasticsearch.client.ml.GetJobRequest;
import org.elasticsearch.client.ml.GetJobStatsRequest;
@@ -224,6 +225,23 @@ public void testPutDatafeed() throws IOException {
}
}
+ public void testGetDatafeed() {
+ GetDatafeedRequest getDatafeedRequest = new GetDatafeedRequest();
+
+ Request request = MLRequestConverters.getDatafeed(getDatafeedRequest);
+
+ assertEquals(HttpGet.METHOD_NAME, request.getMethod());
+ assertEquals("/_xpack/ml/datafeeds", request.getEndpoint());
+ assertFalse(request.getParameters().containsKey("allow_no_datafeeds"));
+
+ getDatafeedRequest = new GetDatafeedRequest("feed-1", "feed-*");
+ getDatafeedRequest.setAllowNoDatafeeds(true);
+ request = MLRequestConverters.getDatafeed(getDatafeedRequest);
+
+ assertEquals("/_xpack/ml/datafeeds/feed-1,feed-*", request.getEndpoint());
+ assertEquals(Boolean.toString(true), request.getParameters().get("allow_no_datafeeds"));
+ }
+
public void testDeleteDatafeed() {
String datafeedId = randomAlphaOfLength(10);
DeleteDatafeedRequest deleteDatafeedRequest = new DeleteDatafeedRequest(datafeedId);
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/MachineLearningIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/MachineLearningIT.java
index a07b441484386..cefd725a5e543 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/MachineLearningIT.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/MachineLearningIT.java
@@ -32,6 +32,8 @@
import org.elasticsearch.client.ml.FlushJobResponse;
import org.elasticsearch.client.ml.ForecastJobRequest;
import org.elasticsearch.client.ml.ForecastJobResponse;
+import org.elasticsearch.client.ml.GetDatafeedRequest;
+import org.elasticsearch.client.ml.GetDatafeedResponse;
import org.elasticsearch.client.ml.GetJobRequest;
import org.elasticsearch.client.ml.GetJobResponse;
import org.elasticsearch.client.ml.GetJobStatsRequest;
@@ -54,6 +56,7 @@
import org.elasticsearch.client.ml.job.config.JobUpdate;
import org.elasticsearch.client.ml.job.stats.JobStats;
import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.rest.RestStatus;
import org.junit.After;
import java.io.IOException;
@@ -312,6 +315,84 @@ public void testPutDatafeed() throws Exception {
assertThat(createdDatafeed.getIndices(), equalTo(datafeedConfig.getIndices()));
}
+ public void testGetDatafeed() throws Exception {
+ String jobId1 = "test-get-datafeed-job-1";
+ String jobId2 = "test-get-datafeed-job-2";
+ Job job1 = buildJob(jobId1);
+ Job job2 = buildJob(jobId2);
+ MachineLearningClient machineLearningClient = highLevelClient().machineLearning();
+ machineLearningClient.putJob(new PutJobRequest(job1), RequestOptions.DEFAULT);
+ machineLearningClient.putJob(new PutJobRequest(job2), RequestOptions.DEFAULT);
+
+ String datafeedId1 = jobId1 + "-feed";
+ String datafeedId2 = jobId2 + "-feed";
+ DatafeedConfig datafeed1 = DatafeedConfig.builder(datafeedId1, jobId1).setIndices("data_1").build();
+ DatafeedConfig datafeed2 = DatafeedConfig.builder(datafeedId2, jobId2).setIndices("data_2").build();
+ machineLearningClient.putDatafeed(new PutDatafeedRequest(datafeed1), RequestOptions.DEFAULT);
+ machineLearningClient.putDatafeed(new PutDatafeedRequest(datafeed2), RequestOptions.DEFAULT);
+
+ // Test getting specific datafeeds
+ {
+ GetDatafeedRequest request = new GetDatafeedRequest(datafeedId1, datafeedId2);
+ GetDatafeedResponse response = execute(request, machineLearningClient::getDatafeed, machineLearningClient::getDatafeedAsync);
+
+ assertEquals(2, response.count());
+ assertThat(response.datafeeds(), hasSize(2));
+ assertThat(response.datafeeds().stream().map(DatafeedConfig::getId).collect(Collectors.toList()),
+ containsInAnyOrder(datafeedId1, datafeedId2));
+ }
+
+ // Test getting a single one
+ {
+ GetDatafeedRequest request = new GetDatafeedRequest(datafeedId1);
+ GetDatafeedResponse response = execute(request, machineLearningClient::getDatafeed, machineLearningClient::getDatafeedAsync);
+
+ assertTrue(response.count() == 1L);
+ assertThat(response.datafeeds().get(0).getId(), equalTo(datafeedId1));
+ }
+
+ // Test getting all datafeeds explicitly
+ {
+ GetDatafeedRequest request = GetDatafeedRequest.getAllDatafeedsRequest();
+ GetDatafeedResponse response = execute(request, machineLearningClient::getDatafeed, machineLearningClient::getDatafeedAsync);
+
+ assertTrue(response.count() == 2L);
+ assertTrue(response.datafeeds().size() == 2L);
+ assertThat(response.datafeeds().stream().map(DatafeedConfig::getId).collect(Collectors.toList()),
+ hasItems(datafeedId1, datafeedId2));
+ }
+
+ // Test getting all datafeeds implicitly
+ {
+ GetDatafeedResponse response = execute(new GetDatafeedRequest(), machineLearningClient::getDatafeed,
+ machineLearningClient::getDatafeedAsync);
+
+ assertTrue(response.count() >= 2L);
+ assertTrue(response.datafeeds().size() >= 2L);
+ assertThat(response.datafeeds().stream().map(DatafeedConfig::getId).collect(Collectors.toList()),
+ hasItems(datafeedId1, datafeedId2));
+ }
+
+ // Test get missing pattern with allow_no_datafeeds set to true
+ {
+ GetDatafeedRequest request = new GetDatafeedRequest("missing-*");
+
+ GetDatafeedResponse response = execute(request, machineLearningClient::getDatafeed, machineLearningClient::getDatafeedAsync);
+
+ assertThat(response.count(), equalTo(0L));
+ }
+
+ // Test get missing pattern with allow_no_datafeeds set to false
+ {
+ GetDatafeedRequest request = new GetDatafeedRequest("missing-*");
+ request.setAllowNoDatafeeds(false);
+
+ ElasticsearchStatusException e = expectThrows(ElasticsearchStatusException.class,
+ () -> execute(request, machineLearningClient::getDatafeed, machineLearningClient::getDatafeedAsync));
+ assertThat(e.status(), equalTo(RestStatus.NOT_FOUND));
+ }
+ }
+
public void testDeleteDatafeed() throws Exception {
String jobId = randomValidJobId();
Job job = buildJob(jobId);
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MlClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MlClientDocumentationIT.java
index 09d32710eb176..cd2f5a813cdd0 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MlClientDocumentationIT.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MlClientDocumentationIT.java
@@ -45,6 +45,8 @@
import org.elasticsearch.client.ml.GetBucketsResponse;
import org.elasticsearch.client.ml.GetCategoriesRequest;
import org.elasticsearch.client.ml.GetCategoriesResponse;
+import org.elasticsearch.client.ml.GetDatafeedRequest;
+import org.elasticsearch.client.ml.GetDatafeedResponse;
import org.elasticsearch.client.ml.GetInfluencersRequest;
import org.elasticsearch.client.ml.GetInfluencersResponse;
import org.elasticsearch.client.ml.GetJobRequest;
@@ -205,14 +207,14 @@ public void testGetJob() throws Exception {
{
//tag::x-pack-ml-get-job-request
- GetJobRequest request = new GetJobRequest("get-machine-learning-job1", "get-machine-learning-job*"); //<1>
- request.setAllowNoJobs(true); //<2>
+ GetJobRequest request = new GetJobRequest("get-machine-learning-job1", "get-machine-learning-job*"); // <1>
+ request.setAllowNoJobs(true); // <2>
//end::x-pack-ml-get-job-request
//tag::x-pack-ml-get-job-execute
GetJobResponse response = client.machineLearning().getJob(request, RequestOptions.DEFAULT);
- long numberOfJobs = response.count(); //<1>
- List jobs = response.jobs(); //<2>
+ long numberOfJobs = response.count(); // <1>
+ List jobs = response.jobs(); // <2>
//end::x-pack-ml-get-job-execute
assertEquals(2, response.count());
@@ -263,12 +265,12 @@ public void testDeleteJob() throws Exception {
{
//tag::x-pack-delete-ml-job-request
DeleteJobRequest deleteJobRequest = new DeleteJobRequest("my-first-machine-learning-job");
- deleteJobRequest.setForce(false); //<1>
+ deleteJobRequest.setForce(false); // <1>
AcknowledgedResponse deleteJobResponse = client.machineLearning().deleteJob(deleteJobRequest, RequestOptions.DEFAULT);
//end::x-pack-delete-ml-job-request
//tag::x-pack-delete-ml-job-response
- boolean isAcknowledged = deleteJobResponse.isAcknowledged(); //<1>
+ boolean isAcknowledged = deleteJobResponse.isAcknowledged(); // <1>
//end::x-pack-delete-ml-job-response
}
{
@@ -310,13 +312,13 @@ public void testOpenJob() throws Exception {
{
//tag::x-pack-ml-open-job-request
- OpenJobRequest openJobRequest = new OpenJobRequest("opening-my-first-machine-learning-job"); //<1>
- openJobRequest.setTimeout(TimeValue.timeValueMinutes(10)); //<2>
+ OpenJobRequest openJobRequest = new OpenJobRequest("opening-my-first-machine-learning-job"); // <1>
+ openJobRequest.setTimeout(TimeValue.timeValueMinutes(10)); // <2>
//end::x-pack-ml-open-job-request
//tag::x-pack-ml-open-job-execute
OpenJobResponse openJobResponse = client.machineLearning().openJob(openJobRequest, RequestOptions.DEFAULT);
- boolean isOpened = openJobResponse.isOpened(); //<1>
+ boolean isOpened = openJobResponse.isOpened(); // <1>
//end::x-pack-ml-open-job-execute
}
@@ -325,7 +327,7 @@ public void testOpenJob() throws Exception {
ActionListener listener = new ActionListener() {
@Override
public void onResponse(OpenJobResponse openJobResponse) {
- //<1>
+ // <1>
}
@Override
@@ -340,7 +342,7 @@ public void onFailure(Exception e) {
listener = new LatchedActionListener<>(listener, latch);
// tag::x-pack-ml-open-job-execute-async
- client.machineLearning().openJobAsync(openJobRequest, RequestOptions.DEFAULT, listener); //<1>
+ client.machineLearning().openJobAsync(openJobRequest, RequestOptions.DEFAULT, listener); // <1>
// end::x-pack-ml-open-job-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS));
@@ -356,15 +358,15 @@ public void testCloseJob() throws Exception {
client.machineLearning().openJob(new OpenJobRequest(job.getId()), RequestOptions.DEFAULT);
//tag::x-pack-ml-close-job-request
- CloseJobRequest closeJobRequest = new CloseJobRequest("closing-my-first-machine-learning-job", "otherjobs*"); //<1>
- closeJobRequest.setForce(false); //<2>
- closeJobRequest.setAllowNoJobs(true); //<3>
- closeJobRequest.setTimeout(TimeValue.timeValueMinutes(10)); //<4>
+ CloseJobRequest closeJobRequest = new CloseJobRequest("closing-my-first-machine-learning-job", "otherjobs*"); // <1>
+ closeJobRequest.setForce(false); // <2>
+ closeJobRequest.setAllowNoJobs(true); // <3>
+ closeJobRequest.setTimeout(TimeValue.timeValueMinutes(10)); // <4>
//end::x-pack-ml-close-job-request
//tag::x-pack-ml-close-job-execute
CloseJobResponse closeJobResponse = client.machineLearning().closeJob(closeJobRequest, RequestOptions.DEFAULT);
- boolean isClosed = closeJobResponse.isClosed(); //<1>
+ boolean isClosed = closeJobResponse.isClosed(); // <1>
//end::x-pack-ml-close-job-execute
}
@@ -377,7 +379,7 @@ public void testCloseJob() throws Exception {
ActionListener listener = new ActionListener() {
@Override
public void onResponse(CloseJobResponse closeJobResponse) {
- //<1>
+ // <1>
}
@Override
@@ -393,7 +395,7 @@ public void onFailure(Exception e) {
listener = new LatchedActionListener<>(listener, latch);
// tag::x-pack-ml-close-job-execute-async
- client.machineLearning().closeJobAsync(closeJobRequest, RequestOptions.DEFAULT, listener); //<1>
+ client.machineLearning().closeJobAsync(closeJobRequest, RequestOptions.DEFAULT, listener); // <1>
// end::x-pack-ml-close-job-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS));
@@ -424,37 +426,37 @@ public void testUpdateJob() throws Exception {
customSettings.put("custom-setting-1", "custom-value");
//tag::x-pack-ml-update-job-detector-options
- JobUpdate.DetectorUpdate detectorUpdate = new JobUpdate.DetectorUpdate(0, //<1>
- "detector description", //<2>
- detectionRules); //<3>
+ JobUpdate.DetectorUpdate detectorUpdate = new JobUpdate.DetectorUpdate(0, // <1>
+ "detector description", // <2>
+ detectionRules); // <3>
//end::x-pack-ml-update-job-detector-options
//tag::x-pack-ml-update-job-options
- JobUpdate update = new JobUpdate.Builder(jobId) //<1>
- .setDescription("My description") //<2>
- .setAnalysisLimits(new AnalysisLimits(1000L, null)) //<3>
- .setBackgroundPersistInterval(TimeValue.timeValueHours(3)) //<4>
- .setCategorizationFilters(Arrays.asList("categorization-filter")) //<5>
- .setDetectorUpdates(Arrays.asList(detectorUpdate)) //<6>
- .setGroups(Arrays.asList("job-group-1")) //<7>
- .setResultsRetentionDays(10L) //<8>
- .setModelPlotConfig(new ModelPlotConfig(true, null)) //<9>
- .setModelSnapshotRetentionDays(7L) //<10>
- .setCustomSettings(customSettings) //<11>
- .setRenormalizationWindowDays(3L) //<12>
+ JobUpdate update = new JobUpdate.Builder(jobId) // <1>
+ .setDescription("My description") // <2>
+ .setAnalysisLimits(new AnalysisLimits(1000L, null)) // <3>
+ .setBackgroundPersistInterval(TimeValue.timeValueHours(3)) // <4>
+ .setCategorizationFilters(Arrays.asList("categorization-filter")) // <5>
+ .setDetectorUpdates(Arrays.asList(detectorUpdate)) // <6>
+ .setGroups(Arrays.asList("job-group-1")) // <7>
+ .setResultsRetentionDays(10L) // <8>
+ .setModelPlotConfig(new ModelPlotConfig(true, null)) // <9>
+ .setModelSnapshotRetentionDays(7L) // <10>
+ .setCustomSettings(customSettings) // <11>
+ .setRenormalizationWindowDays(3L) // <12>
.build();
//end::x-pack-ml-update-job-options
//tag::x-pack-ml-update-job-request
- UpdateJobRequest updateJobRequest = new UpdateJobRequest(update); //<1>
+ UpdateJobRequest updateJobRequest = new UpdateJobRequest(update); // <1>
//end::x-pack-ml-update-job-request
//tag::x-pack-ml-update-job-execute
PutJobResponse updateJobResponse = client.machineLearning().updateJob(updateJobRequest, RequestOptions.DEFAULT);
//end::x-pack-ml-update-job-execute
//tag::x-pack-ml-update-job-response
- Job updatedJob = updateJobResponse.getResponse(); //<1>
+ Job updatedJob = updateJobResponse.getResponse(); // <1>
//end::x-pack-ml-update-job-response
assertEquals(update.getDescription(), updatedJob.getDescription());
@@ -464,7 +466,7 @@ public void testUpdateJob() throws Exception {
ActionListener listener = new ActionListener() {
@Override
public void onResponse(PutJobResponse updateJobResponse) {
- //<1>
+ // <1>
}
@Override
@@ -480,7 +482,7 @@ public void onFailure(Exception e) {
listener = new LatchedActionListener<>(listener, latch);
// tag::x-pack-ml-update-job-execute-async
- client.machineLearning().updateJobAsync(updateJobRequest, RequestOptions.DEFAULT, listener); //<1>
+ client.machineLearning().updateJobAsync(updateJobRequest, RequestOptions.DEFAULT, listener); // <1>
// end::x-pack-ml-update-job-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS));
@@ -587,6 +589,59 @@ public void onFailure(Exception e) {
}
}
+ public void testGetDatafeed() throws Exception {
+ RestHighLevelClient client = highLevelClient();
+
+ Job job = MachineLearningIT.buildJob("get-datafeed-job");
+ client.machineLearning().putJob(new PutJobRequest(job), RequestOptions.DEFAULT);
+ String datafeedId = job.getId() + "-feed";
+ DatafeedConfig datafeed = DatafeedConfig.builder(datafeedId, job.getId()).setIndices("foo").build();
+ client.machineLearning().putDatafeed(new PutDatafeedRequest(datafeed), RequestOptions.DEFAULT);
+
+ {
+ //tag::x-pack-ml-get-datafeed-request
+ GetDatafeedRequest request = new GetDatafeedRequest(datafeedId); // <1>
+ request.setAllowNoDatafeeds(true); // <2>
+ //end::x-pack-ml-get-datafeed-request
+
+ //tag::x-pack-ml-get-datafeed-execute
+ GetDatafeedResponse response = client.machineLearning().getDatafeed(request, RequestOptions.DEFAULT);
+ long numberOfDatafeeds = response.count(); // <1>
+ List datafeeds = response.datafeeds(); // <2>
+ //end::x-pack-ml-get-datafeed-execute
+
+ assertEquals(1, numberOfDatafeeds);
+ assertEquals(1, datafeeds.size());
+ }
+ {
+ GetDatafeedRequest request = new GetDatafeedRequest(datafeedId);
+
+ // tag::x-pack-ml-get-datafeed-listener
+ ActionListener listener = new ActionListener() {
+ @Override
+ public void onResponse(GetDatafeedResponse response) {
+ // <1>
+ }
+
+ @Override
+ public void onFailure(Exception e) {
+ // <2>
+ }
+ };
+ // end::x-pack-ml-get-datafeed-listener
+
+ // Replace the empty listener by a blocking listener in test
+ final CountDownLatch latch = new CountDownLatch(1);
+ listener = new LatchedActionListener<>(listener, latch);
+
+ // tag::x-pack-ml-get-datafeed-execute-async
+ client.machineLearning().getDatafeedAsync(request, RequestOptions.DEFAULT, listener); // <1>
+ // end::x-pack-ml-get-datafeed-execute-async
+
+ assertTrue(latch.await(30L, TimeUnit.SECONDS));
+ }
+ }
+
public void testDeleteDatafeed() throws Exception {
RestHighLevelClient client = highLevelClient();
@@ -601,13 +656,13 @@ public void testDeleteDatafeed() throws Exception {
{
//tag::x-pack-delete-ml-datafeed-request
DeleteDatafeedRequest deleteDatafeedRequest = new DeleteDatafeedRequest(datafeedId);
- deleteDatafeedRequest.setForce(false); //<1>
+ deleteDatafeedRequest.setForce(false); // <1>
AcknowledgedResponse deleteDatafeedResponse = client.machineLearning().deleteDatafeed(
deleteDatafeedRequest, RequestOptions.DEFAULT);
//end::x-pack-delete-ml-datafeed-request
//tag::x-pack-delete-ml-datafeed-response
- boolean isAcknowledged = deleteDatafeedResponse.isAcknowledged(); //<1>
+ boolean isAcknowledged = deleteDatafeedResponse.isAcknowledged(); // <1>
//end::x-pack-delete-ml-datafeed-response
}
@@ -756,15 +811,15 @@ public void testFlushJob() throws Exception {
{
//tag::x-pack-ml-flush-job-request
- FlushJobRequest flushJobRequest = new FlushJobRequest("flushing-my-first-machine-learning-job"); //<1>
+ FlushJobRequest flushJobRequest = new FlushJobRequest("flushing-my-first-machine-learning-job"); // <1>
//end::x-pack-ml-flush-job-request
//tag::x-pack-ml-flush-job-request-options
- flushJobRequest.setCalcInterim(true); //<1>
- flushJobRequest.setAdvanceTime("2018-08-31T16:35:07+00:00"); //<2>
- flushJobRequest.setStart("2018-08-31T16:35:17+00:00"); //<3>
- flushJobRequest.setEnd("2018-08-31T16:35:27+00:00"); //<4>
- flushJobRequest.setSkipTime("2018-08-31T16:35:00+00:00"); //<5>
+ flushJobRequest.setCalcInterim(true); // <1>
+ flushJobRequest.setAdvanceTime("2018-08-31T16:35:07+00:00"); // <2>
+ flushJobRequest.setStart("2018-08-31T16:35:17+00:00"); // <3>
+ flushJobRequest.setEnd("2018-08-31T16:35:27+00:00"); // <4>
+ flushJobRequest.setSkipTime("2018-08-31T16:35:00+00:00"); // <5>
//end::x-pack-ml-flush-job-request-options
//tag::x-pack-ml-flush-job-execute
@@ -772,8 +827,8 @@ public void testFlushJob() throws Exception {
//end::x-pack-ml-flush-job-execute
//tag::x-pack-ml-flush-job-response
- boolean isFlushed = flushJobResponse.isFlushed(); //<1>
- Date lastFinalizedBucketEnd = flushJobResponse.getLastFinalizedBucketEnd(); //<2>
+ boolean isFlushed = flushJobResponse.isFlushed(); // <1>
+ Date lastFinalizedBucketEnd = flushJobResponse.getLastFinalizedBucketEnd(); // <2>
//end::x-pack-ml-flush-job-response
}
@@ -782,7 +837,7 @@ public void testFlushJob() throws Exception {
ActionListener listener = new ActionListener() {
@Override
public void onResponse(FlushJobResponse FlushJobResponse) {
- //<1>
+ // <1>
}
@Override
@@ -798,7 +853,7 @@ public void onFailure(Exception e) {
listener = new LatchedActionListener<>(listener, latch);
// tag::x-pack-ml-flush-job-execute-async
- client.machineLearning().flushJobAsync(flushJobRequest, RequestOptions.DEFAULT, listener); //<1>
+ client.machineLearning().flushJobAsync(flushJobRequest, RequestOptions.DEFAULT, listener); // <1>
// end::x-pack-ml-flush-job-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS));
@@ -836,13 +891,13 @@ public void testDeleteForecast() throws Exception {
{
//tag::x-pack-ml-delete-forecast-request
- DeleteForecastRequest deleteForecastRequest = new DeleteForecastRequest("deleting-forecast-for-job"); //<1>
+ DeleteForecastRequest deleteForecastRequest = new DeleteForecastRequest("deleting-forecast-for-job"); // <1>
//end::x-pack-ml-delete-forecast-request
//tag::x-pack-ml-delete-forecast-request-options
- deleteForecastRequest.setForecastIds(forecastId); //<1>
- deleteForecastRequest.timeout("30s"); //<2>
- deleteForecastRequest.setAllowNoForecasts(true); //<3>
+ deleteForecastRequest.setForecastIds(forecastId); // <1>
+ deleteForecastRequest.timeout("30s"); // <2>
+ deleteForecastRequest.setAllowNoForecasts(true); // <3>
//end::x-pack-ml-delete-forecast-request-options
//tag::x-pack-ml-delete-forecast-execute
@@ -851,7 +906,7 @@ public void testDeleteForecast() throws Exception {
//end::x-pack-ml-delete-forecast-execute
//tag::x-pack-ml-delete-forecast-response
- boolean isAcknowledged = deleteForecastResponse.isAcknowledged(); //<1>
+ boolean isAcknowledged = deleteForecastResponse.isAcknowledged(); // <1>
//end::x-pack-ml-delete-forecast-response
}
{
@@ -859,7 +914,7 @@ public void testDeleteForecast() throws Exception {
ActionListener listener = new ActionListener() {
@Override
public void onResponse(AcknowledgedResponse DeleteForecastResponse) {
- //<1>
+ // <1>
}
@Override
@@ -876,7 +931,7 @@ public void onFailure(Exception e) {
listener = new LatchedActionListener<>(listener, latch);
// tag::x-pack-ml-delete-forecast-execute-async
- client.machineLearning().deleteForecastAsync(deleteForecastRequest, RequestOptions.DEFAULT, listener); //<1>
+ client.machineLearning().deleteForecastAsync(deleteForecastRequest, RequestOptions.DEFAULT, listener); // <1>
// end::x-pack-ml-delete-forecast-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS));
@@ -894,8 +949,8 @@ public void testGetJobStats() throws Exception {
{
//tag::x-pack-ml-get-job-stats-request
- GetJobStatsRequest request = new GetJobStatsRequest("get-machine-learning-job-stats1", "get-machine-learning-job-*"); //<1>
- request.setAllowNoJobs(true); //<2>
+ GetJobStatsRequest request = new GetJobStatsRequest("get-machine-learning-job-stats1", "get-machine-learning-job-*"); // <1>
+ request.setAllowNoJobs(true); // <2>
//end::x-pack-ml-get-job-stats-request
//tag::x-pack-ml-get-job-stats-execute
@@ -903,8 +958,8 @@ public void testGetJobStats() throws Exception {
//end::x-pack-ml-get-job-stats-execute
//tag::x-pack-ml-get-job-stats-response
- long numberOfJobStats = response.count(); //<1>
- List jobStats = response.jobStats(); //<2>
+ long numberOfJobStats = response.count(); // <1>
+ List jobStats = response.jobStats(); // <2>
//end::x-pack-ml-get-job-stats-response
assertEquals(2, response.count());
@@ -961,12 +1016,12 @@ public void testForecastJob() throws Exception {
{
//tag::x-pack-ml-forecast-job-request
- ForecastJobRequest forecastJobRequest = new ForecastJobRequest("forecasting-my-first-machine-learning-job"); //<1>
+ ForecastJobRequest forecastJobRequest = new ForecastJobRequest("forecasting-my-first-machine-learning-job"); // <1>
//end::x-pack-ml-forecast-job-request
//tag::x-pack-ml-forecast-job-request-options
- forecastJobRequest.setExpiresIn(TimeValue.timeValueHours(48)); //<1>
- forecastJobRequest.setDuration(TimeValue.timeValueHours(24)); //<2>
+ forecastJobRequest.setExpiresIn(TimeValue.timeValueHours(48)); // <1>
+ forecastJobRequest.setDuration(TimeValue.timeValueHours(24)); // <2>
//end::x-pack-ml-forecast-job-request-options
//tag::x-pack-ml-forecast-job-execute
@@ -974,8 +1029,8 @@ public void testForecastJob() throws Exception {
//end::x-pack-ml-forecast-job-execute
//tag::x-pack-ml-forecast-job-response
- boolean isAcknowledged = forecastJobResponse.isAcknowledged(); //<1>
- String forecastId = forecastJobResponse.getForecastId(); //<2>
+ boolean isAcknowledged = forecastJobResponse.isAcknowledged(); // <1>
+ String forecastId = forecastJobResponse.getForecastId(); // <2>
//end::x-pack-ml-forecast-job-response
assertTrue(isAcknowledged);
assertNotNull(forecastId);
@@ -985,7 +1040,7 @@ public void testForecastJob() throws Exception {
ActionListener listener = new ActionListener() {
@Override
public void onResponse(ForecastJobResponse forecastJobResponse) {
- //<1>
+ // <1>
}
@Override
@@ -1001,7 +1056,7 @@ public void onFailure(Exception e) {
listener = new LatchedActionListener<>(listener, latch);
// tag::x-pack-ml-forecast-job-execute-async
- client.machineLearning().forecastJobAsync(forecastJobRequest, RequestOptions.DEFAULT, listener); //<1>
+ client.machineLearning().forecastJobAsync(forecastJobRequest, RequestOptions.DEFAULT, listener); // <1>
// end::x-pack-ml-forecast-job-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS));
@@ -1208,18 +1263,18 @@ public void testPostData() throws Exception {
{
//tag::x-pack-ml-post-data-request
- PostDataRequest.JsonBuilder jsonBuilder = new PostDataRequest.JsonBuilder(); //<1>
+ PostDataRequest.JsonBuilder jsonBuilder = new PostDataRequest.JsonBuilder(); // <1>
Map mapData = new HashMap<>();
mapData.put("total", 109);
- jsonBuilder.addDoc(mapData); //<2>
- jsonBuilder.addDoc("{\"total\":1000}"); //<3>
- PostDataRequest postDataRequest = new PostDataRequest("test-post-data", jsonBuilder); //<4>
+ jsonBuilder.addDoc(mapData); // <2>
+ jsonBuilder.addDoc("{\"total\":1000}"); // <3>
+ PostDataRequest postDataRequest = new PostDataRequest("test-post-data", jsonBuilder); // <4>
//end::x-pack-ml-post-data-request
//tag::x-pack-ml-post-data-request-options
- postDataRequest.setResetStart("2018-08-31T16:35:07+00:00"); //<1>
- postDataRequest.setResetEnd("2018-08-31T16:35:17+00:00"); //<2>
+ postDataRequest.setResetStart("2018-08-31T16:35:07+00:00"); // <1>
+ postDataRequest.setResetEnd("2018-08-31T16:35:17+00:00"); // <2>
//end::x-pack-ml-post-data-request-options
postDataRequest.setResetEnd(null);
postDataRequest.setResetStart(null);
@@ -1229,7 +1284,7 @@ public void testPostData() throws Exception {
//end::x-pack-ml-post-data-execute
//tag::x-pack-ml-post-data-response
- DataCounts dataCounts = postDataResponse.getDataCounts(); //<1>
+ DataCounts dataCounts = postDataResponse.getDataCounts(); // <1>
//end::x-pack-ml-post-data-response
assertEquals(2, dataCounts.getInputRecordCount());
@@ -1239,7 +1294,7 @@ public void testPostData() throws Exception {
ActionListener listener = new ActionListener() {
@Override
public void onResponse(PostDataResponse postDataResponse) {
- //<1>
+ // <1>
}
@Override
@@ -1252,14 +1307,14 @@ public void onFailure(Exception e) {
Map mapData = new HashMap<>();
mapData.put("total", 109);
jsonBuilder.addDoc(mapData);
- PostDataRequest postDataRequest = new PostDataRequest("test-post-data", jsonBuilder); //<1>
+ PostDataRequest postDataRequest = new PostDataRequest("test-post-data", jsonBuilder); // <1>
// Replace the empty listener by a blocking listener in test
final CountDownLatch latch = new CountDownLatch(1);
listener = new LatchedActionListener<>(listener, latch);
// tag::x-pack-ml-post-data-execute-async
- client.machineLearning().postDataAsync(postDataRequest, RequestOptions.DEFAULT, listener); //<1>
+ client.machineLearning().postDataAsync(postDataRequest, RequestOptions.DEFAULT, listener); // <1>
// end::x-pack-ml-post-data-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS));
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/GetDatafeedRequestTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/GetDatafeedRequestTests.java
new file mode 100644
index 0000000000000..cca63d2f29efd
--- /dev/null
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/GetDatafeedRequestTests.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.elasticsearch.client.ml;
+
+import org.elasticsearch.client.ml.datafeed.DatafeedConfigTests;
+import org.elasticsearch.common.xcontent.XContentParser;
+import org.elasticsearch.test.AbstractXContentTestCase;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class GetDatafeedRequestTests extends AbstractXContentTestCase {
+
+ public void testAllDatafeedRequest() {
+ GetDatafeedRequest request = GetDatafeedRequest.getAllDatafeedsRequest();
+
+ assertEquals(request.getDatafeedIds().size(), 1);
+ assertEquals(request.getDatafeedIds().get(0), "_all");
+ }
+
+ public void testNewWithDatafeedId() {
+ Exception exception = expectThrows(NullPointerException.class, () -> new GetDatafeedRequest("feed",null));
+ assertEquals(exception.getMessage(), "datafeedIds must not contain null values");
+ }
+
+ @Override
+ protected GetDatafeedRequest createTestInstance() {
+ int count = randomIntBetween(0, 10);
+ List datafeedIds = new ArrayList<>(count);
+
+ for (int i = 0; i < count; i++) {
+ datafeedIds.add(DatafeedConfigTests.randomValidDatafeedId());
+ }
+
+ GetDatafeedRequest request = new GetDatafeedRequest(datafeedIds);
+
+ if (randomBoolean()) {
+ request.setAllowNoDatafeeds(randomBoolean());
+ }
+
+ return request;
+ }
+
+ @Override
+ protected GetDatafeedRequest doParseInstance(XContentParser parser) throws IOException {
+ return GetDatafeedRequest.PARSER.parse(parser, null);
+ }
+
+ @Override
+ protected boolean supportsUnknownFields() {
+ return false;
+ }
+}
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/GetDatafeedResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/GetDatafeedResponseTests.java
new file mode 100644
index 0000000000000..e4c93c9d8aca8
--- /dev/null
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/GetDatafeedResponseTests.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.elasticsearch.client.ml;
+
+import org.elasticsearch.client.ml.datafeed.DatafeedConfig;
+import org.elasticsearch.client.ml.datafeed.DatafeedConfigTests;
+import org.elasticsearch.common.xcontent.XContentParser;
+import org.elasticsearch.test.AbstractXContentTestCase;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Predicate;
+
+public class GetDatafeedResponseTests extends AbstractXContentTestCase {
+
+ @Override
+ protected GetDatafeedResponse createTestInstance() {
+ int count = randomIntBetween(1, 5);
+ List results = new ArrayList<>(count);
+ for(int i = 0; i < count; i++) {
+ DatafeedConfigTests.createRandomBuilder();
+ results.add(DatafeedConfigTests.createRandomBuilder());
+ }
+ return new GetDatafeedResponse(results, count);
+ }
+
+ @Override
+ protected GetDatafeedResponse doParseInstance(XContentParser parser) throws IOException {
+ return GetDatafeedResponse.fromXContent(parser);
+ }
+
+ @Override
+ protected Predicate getRandomFieldsExcludeFilter() {
+ return field -> !field.isEmpty();
+ }
+
+ @Override
+ protected boolean supportsUnknownFields() {
+ return true;
+ }
+}
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/GetJobRequestTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/GetJobRequestTests.java
index 77b2109dd7c68..36aa02dbd62b7 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/GetJobRequestTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/GetJobRequestTests.java
@@ -64,6 +64,6 @@ protected GetJobRequest doParseInstance(XContentParser parser) throws IOExceptio
@Override
protected boolean supportsUnknownFields() {
- return true;
+ return false;
}
}
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/datafeed/DatafeedConfigTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/datafeed/DatafeedConfigTests.java
index e4e16c45fbfdf..4cf23978c2546 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/datafeed/DatafeedConfigTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/datafeed/DatafeedConfigTests.java
@@ -44,6 +44,10 @@ protected DatafeedConfig createTestInstance() {
}
public static DatafeedConfig createRandom() {
+ return createRandomBuilder().build();
+ }
+
+ public static DatafeedConfig.Builder createRandomBuilder() {
long bucketSpanMillis = 3600000;
DatafeedConfig.Builder builder = constructBuilder();
builder.setIndices(randomStringList(1, 10));
@@ -99,7 +103,7 @@ public static DatafeedConfig createRandom() {
if (randomBoolean()) {
builder.setChunkingConfig(ChunkingConfigTests.createRandomizedChunk());
}
- return builder.build();
+ return builder;
}
public static List randomStringList(int min, int max) {
diff --git a/docs/java-rest/high-level/ml/get-datafeed.asciidoc b/docs/java-rest/high-level/ml/get-datafeed.asciidoc
new file mode 100644
index 0000000000000..8e5f0664c6181
--- /dev/null
+++ b/docs/java-rest/high-level/ml/get-datafeed.asciidoc
@@ -0,0 +1,56 @@
+[[java-rest-high-x-pack-ml-get-datafeed]]
+=== Get Datafeed API
+
+The Get Datafeed API provides the ability to get {ml} datafeeds in the cluster.
+It accepts a `GetDatafeedRequest` object and responds
+with a `GetDatafeedResponse` object.
+
+[[java-rest-high-x-pack-ml-get-datafeed-request]]
+==== Get Datafeed Request
+
+A `GetDatafeedRequest` object gets can have any number of `datafeedId` entries.
+However, they all must be non-null. An empty list is the same as requesting for all datafeeds.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-get-datafeed-request]
+--------------------------------------------------
+<1> Constructing a new request referencing existing `datafeedIds`, can contain wildcards
+<2> Whether to ignore if a wildcard expression matches no datafeeds.
+ (This includes `_all` string or when no datafeeds have been specified)
+
+[[java-rest-high-x-pack-ml-get-datafeed-execution]]
+==== Execution
+
+The request can be executed through the `MachineLearningClient` contained
+in the `RestHighLevelClient` object, accessed via the `machineLearningClient()` method.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-get-datafeed-execute]
+--------------------------------------------------
+<1> The count of retrieved datafeeds
+<2> The retrieved datafeeds
+
+[[java-rest-high-x-pack-ml-get-datafeed-execution-async]]
+==== Asynchronous Execution
+
+The request can also be executed asynchronously:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-get-datafeed-execute-async]
+--------------------------------------------------
+<1> The `GetDatafeedRequest` to execute and the `ActionListener` to use when
+the execution completes
+
+The method does not block and returns immediately. The passed `ActionListener` is used
+to notify the caller of completion. A typical `ActionListener` for `GetDatafeedResponse` may
+look like
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-get-datafeed-listener]
+--------------------------------------------------
+<1> `onResponse` is called back when the action is completed successfully
+<2> `onFailure` is called back when some unexpected error occurs
diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc
index cb297d0f712dc..60819cd3935eb 100644
--- a/docs/java-rest/high-level/supported-apis.asciidoc
+++ b/docs/java-rest/high-level/supported-apis.asciidoc
@@ -221,6 +221,7 @@ The Java High Level REST Client supports the following Machine Learning APIs:
* <>
* <>
* <>
+* <>
* <>
* <>
* <>
@@ -239,6 +240,7 @@ include::ml/close-job.asciidoc[]
include::ml/update-job.asciidoc[]
include::ml/flush-job.asciidoc[]
include::ml/put-datafeed.asciidoc[]
+include::ml/get-datafeed.asciidoc[]
include::ml/delete-datafeed.asciidoc[]
include::ml/get-job-stats.asciidoc[]
include::ml/forecast-job.asciidoc[]