[HLRC][ML] Add ML get datafeed API to HLRC (#33715)

Relates #29827
This commit is contained in:
Dimitris Athanasiou 2018-09-16 11:54:55 +01:00 committed by GitHub
parent 73417bf09a
commit db40315afb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 736 additions and 97 deletions

View File

@ -35,6 +35,7 @@ import org.elasticsearch.client.ml.FlushJobRequest;
import org.elasticsearch.client.ml.ForecastJobRequest; import org.elasticsearch.client.ml.ForecastJobRequest;
import org.elasticsearch.client.ml.GetBucketsRequest; import org.elasticsearch.client.ml.GetBucketsRequest;
import org.elasticsearch.client.ml.GetCategoriesRequest; import org.elasticsearch.client.ml.GetCategoriesRequest;
import org.elasticsearch.client.ml.GetDatafeedRequest;
import org.elasticsearch.client.ml.GetInfluencersRequest; import org.elasticsearch.client.ml.GetInfluencersRequest;
import org.elasticsearch.client.ml.GetJobRequest; import org.elasticsearch.client.ml.GetJobRequest;
import org.elasticsearch.client.ml.GetJobStatsRequest; import org.elasticsearch.client.ml.GetJobStatsRequest;
@ -197,6 +198,24 @@ final class MLRequestConverters {
return request; return request;
} }
static Request getDatafeed(GetDatafeedRequest getDatafeedRequest) {
String endpoint = new EndpointBuilder()
.addPathPartAsIs("_xpack")
.addPathPartAsIs("ml")
.addPathPartAsIs("datafeeds")
.addPathPart(Strings.collectionToCommaDelimitedString(getDatafeedRequest.getDatafeedIds()))
.build();
Request request = new Request(HttpGet.METHOD_NAME, endpoint);
RequestConverters.Params params = new RequestConverters.Params(request);
if (getDatafeedRequest.isAllowNoDatafeeds() != null) {
params.putParam(GetDatafeedRequest.ALLOW_NO_DATAFEEDS.getPreferredName(),
Boolean.toString(getDatafeedRequest.isAllowNoDatafeeds()));
}
return request;
}
static Request deleteDatafeed(DeleteDatafeedRequest deleteDatafeedRequest) { static Request deleteDatafeed(DeleteDatafeedRequest deleteDatafeedRequest) {
String endpoint = new EndpointBuilder() String endpoint = new EndpointBuilder()
.addPathPartAsIs("_xpack") .addPathPartAsIs("_xpack")

View File

@ -33,6 +33,8 @@ import org.elasticsearch.client.ml.GetBucketsRequest;
import org.elasticsearch.client.ml.GetBucketsResponse; import org.elasticsearch.client.ml.GetBucketsResponse;
import org.elasticsearch.client.ml.GetCategoriesRequest; import org.elasticsearch.client.ml.GetCategoriesRequest;
import org.elasticsearch.client.ml.GetCategoriesResponse; 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.GetInfluencersRequest;
import org.elasticsearch.client.ml.GetInfluencersResponse; import org.elasticsearch.client.ml.GetInfluencersResponse;
import org.elasticsearch.client.ml.GetJobRequest; import org.elasticsearch.client.ml.GetJobRequest;
@ -466,8 +468,8 @@ public final class MachineLearningClient {
* For additional info * For additional info
* see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ml-put-datafeed.html">ML PUT datafeed documentation</a> * see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ml-put-datafeed.html">ML PUT datafeed documentation</a>
* *
* @param request The request containing the {@link org.elasticsearch.client.ml.datafeed.DatafeedConfig} settings * @param request The request containing the {@link org.elasticsearch.client.ml.datafeed.DatafeedConfig} settings
* @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized * @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @param listener Listener to be notified upon request completion * @param listener Listener to be notified upon request completion
*/ */
public void putDatafeedAsync(PutDatafeedRequest request, RequestOptions options, ActionListener<PutDatafeedResponse> listener) { public void putDatafeedAsync(PutDatafeedRequest request, RequestOptions options, ActionListener<PutDatafeedResponse> listener) {
@ -479,6 +481,47 @@ public final class MachineLearningClient {
Collections.emptySet()); Collections.emptySet());
} }
/**
* Gets one or more Machine Learning datafeed configuration info.
*
* <p>
* For additional info
* see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-datafeed.html">ML GET datafeed documentation</a>
*
* @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.
*
* <p>
* For additional info
* see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-datafeed.html">ML GET datafeed documentation</a>
*
* @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<GetDatafeedResponse> listener) {
restHighLevelClient.performRequestAsyncAndParseEntity(request,
MLRequestConverters::getDatafeed,
options,
GetDatafeedResponse::fromXContent,
listener,
Collections.emptySet());
}
/** /**
* Deletes the given Machine Learning Datafeed * Deletes the given Machine Learning Datafeed
* <p> * <p>

View File

@ -136,9 +136,9 @@ public class CloseJobRequest extends ActionRequest implements ToXContentObject {
/** /**
* Whether to ignore if a wildcard expression matches no jobs. * 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) { public void setAllowNoJobs(boolean allowNoJobs) {
this.allowNoJobs = allowNoJobs; this.allowNoJobs = allowNoJobs;

View File

@ -109,7 +109,7 @@ public class DeleteForecastRequest extends ActionRequest implements ToXContentOb
} }
/** /**
* 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 * @param allowNoForecasts when {@code true} no error is thrown when {@link DeleteForecastRequest#ALL} does not find any forecasts
*/ */

View File

@ -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<String> datafeedIds;
private Boolean allowNoDatafeeds;
@SuppressWarnings("unchecked")
public static final ConstructingObjectParser<GetDatafeedRequest, Void> PARSER = new ConstructingObjectParser<>(
"get_datafeed_request",
true, a -> new GetDatafeedRequest(a[0] == null ? new ArrayList<>() : (List<String>) 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<String> 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<String> 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;
}
}

View File

@ -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<DatafeedConfig> {
public static final ParseField RESULTS_FIELD = new ParseField("datafeeds");
@SuppressWarnings("unchecked")
public static final ConstructingObjectParser<GetDatafeedResponse, Void> PARSER =
new ConstructingObjectParser<>("get_datafeed_response", true,
a -> new GetDatafeedResponse((List<DatafeedConfig.Builder>) a[0], (long) a[1]));
static {
PARSER.declareObjectArray(constructorArg(), DatafeedConfig.PARSER, RESULTS_FIELD);
PARSER.declareLong(constructorArg(), AbstractResultResponse.COUNT);
}
GetDatafeedResponse(List<DatafeedConfig.Builder> 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<DatafeedConfig> 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);
}
}

View File

@ -33,11 +33,11 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
/** /**
* Request object to get {@link Job} objects with the matching `jobId`s or * Request object to get {@link Job} objects with the matching {@code jobId}s or
* `groupName`s. * {@code groupName}s.
* *
* `_all` explicitly gets all the jobs in the cluster * {@code _all} explicitly gets all the jobs in the cluster
* An empty request (no `jobId`s) implicitly 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 { public class GetJobRequest extends ActionRequest implements ToXContentObject {
@ -91,7 +91,7 @@ public class GetJobRequest extends ActionRequest implements ToXContentObject {
/** /**
* Whether to ignore if a wildcard expression matches no jobs. * 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) { public void setAllowNoJobs(boolean allowNoJobs) {
this.allowNoJobs = allowNoJobs; this.allowNoJobs = allowNoJobs;

View File

@ -38,8 +38,8 @@ import java.util.Objects;
/** /**
* Request object to get {@link org.elasticsearch.client.ml.job.stats.JobStats} by their respective jobIds * 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 * {@code _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 * An empty request (no {@code jobId}s) implicitly gets all the jobs' statistics in the cluster
*/ */
public class GetJobStatsRequest extends ActionRequest implements ToXContentObject { public class GetJobStatsRequest extends ActionRequest implements ToXContentObject {
@ -100,9 +100,9 @@ public class GetJobStatsRequest extends ActionRequest implements ToXContentObjec
/** /**
* Whether to ignore if a wildcard expression matches no jobs. * 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) { public void setAllowNoJobs(boolean allowNoJobs) {
this.allowNoJobs = allowNoJobs; this.allowNoJobs = allowNoJobs;

View File

@ -109,7 +109,7 @@ public class GetOverallBucketsRequest extends ActionRequest implements ToXConten
} }
/** /**
* 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. * @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) { public void setTopN(Integer topN) {
@ -121,7 +121,7 @@ public class GetOverallBucketsRequest extends ActionRequest implements ToXConten
} }
/** /**
* 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 jobs bucket_span. * @param bucketSpan The span of the overall buckets. Must be greater or equal to the largest jobs bucket_span.
* Defaults to the largest jobs bucket_span. * Defaults to the largest jobs bucket_span.
*/ */
@ -197,7 +197,7 @@ public class GetOverallBucketsRequest extends ActionRequest implements ToXConten
/** /**
* Whether to ignore if a wildcard expression matches no jobs. * 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() { public Boolean isAllowNoJobs() {
return allowNoJobs; return allowNoJobs;

View File

@ -38,7 +38,7 @@ import java.util.Map;
import java.util.Objects; 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 { public class PostDataRequest extends ActionRequest implements ToXContentObject {

View File

@ -31,6 +31,7 @@ import org.elasticsearch.client.ml.FlushJobRequest;
import org.elasticsearch.client.ml.ForecastJobRequest; import org.elasticsearch.client.ml.ForecastJobRequest;
import org.elasticsearch.client.ml.GetBucketsRequest; import org.elasticsearch.client.ml.GetBucketsRequest;
import org.elasticsearch.client.ml.GetCategoriesRequest; import org.elasticsearch.client.ml.GetCategoriesRequest;
import org.elasticsearch.client.ml.GetDatafeedRequest;
import org.elasticsearch.client.ml.GetInfluencersRequest; import org.elasticsearch.client.ml.GetInfluencersRequest;
import org.elasticsearch.client.ml.GetJobRequest; import org.elasticsearch.client.ml.GetJobRequest;
import org.elasticsearch.client.ml.GetJobStatsRequest; import org.elasticsearch.client.ml.GetJobStatsRequest;
@ -227,6 +228,23 @@ public class MLRequestConvertersTests extends ESTestCase {
} }
} }
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() { public void testDeleteDatafeed() {
String datafeedId = randomAlphaOfLength(10); String datafeedId = randomAlphaOfLength(10);
DeleteDatafeedRequest deleteDatafeedRequest = new DeleteDatafeedRequest(datafeedId); DeleteDatafeedRequest deleteDatafeedRequest = new DeleteDatafeedRequest(datafeedId);

View File

@ -32,6 +32,8 @@ import org.elasticsearch.client.ml.FlushJobRequest;
import org.elasticsearch.client.ml.FlushJobResponse; import org.elasticsearch.client.ml.FlushJobResponse;
import org.elasticsearch.client.ml.ForecastJobRequest; import org.elasticsearch.client.ml.ForecastJobRequest;
import org.elasticsearch.client.ml.ForecastJobResponse; 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.GetJobRequest;
import org.elasticsearch.client.ml.GetJobResponse; import org.elasticsearch.client.ml.GetJobResponse;
import org.elasticsearch.client.ml.GetJobStatsRequest; import org.elasticsearch.client.ml.GetJobStatsRequest;
@ -58,6 +60,7 @@ import org.elasticsearch.client.ml.job.config.JobState;
import org.elasticsearch.client.ml.job.config.JobUpdate; import org.elasticsearch.client.ml.job.config.JobUpdate;
import org.elasticsearch.client.ml.job.stats.JobStats; import org.elasticsearch.client.ml.job.stats.JobStats;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.rest.RestStatus;
import org.junit.After; import org.junit.After;
import java.io.IOException; import java.io.IOException;
@ -316,6 +319,84 @@ public class MachineLearningIT extends ESRestHighLevelClientTestCase {
assertThat(createdDatafeed.getIndices(), equalTo(datafeedConfig.getIndices())); 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 { public void testDeleteDatafeed() throws Exception {
String jobId = randomValidJobId(); String jobId = randomValidJobId();
Job job = buildJob(jobId); Job job = buildJob(jobId);

View File

@ -45,6 +45,8 @@ import org.elasticsearch.client.ml.GetBucketsRequest;
import org.elasticsearch.client.ml.GetBucketsResponse; import org.elasticsearch.client.ml.GetBucketsResponse;
import org.elasticsearch.client.ml.GetCategoriesRequest; import org.elasticsearch.client.ml.GetCategoriesRequest;
import org.elasticsearch.client.ml.GetCategoriesResponse; 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.GetInfluencersRequest;
import org.elasticsearch.client.ml.GetInfluencersResponse; import org.elasticsearch.client.ml.GetInfluencersResponse;
import org.elasticsearch.client.ml.GetJobRequest; import org.elasticsearch.client.ml.GetJobRequest;
@ -208,14 +210,14 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
{ {
//tag::x-pack-ml-get-job-request //tag::x-pack-ml-get-job-request
GetJobRequest request = new GetJobRequest("get-machine-learning-job1", "get-machine-learning-job*"); //<1> GetJobRequest request = new GetJobRequest("get-machine-learning-job1", "get-machine-learning-job*"); // <1>
request.setAllowNoJobs(true); //<2> request.setAllowNoJobs(true); // <2>
//end::x-pack-ml-get-job-request //end::x-pack-ml-get-job-request
//tag::x-pack-ml-get-job-execute //tag::x-pack-ml-get-job-execute
GetJobResponse response = client.machineLearning().getJob(request, RequestOptions.DEFAULT); GetJobResponse response = client.machineLearning().getJob(request, RequestOptions.DEFAULT);
long numberOfJobs = response.count(); //<1> long numberOfJobs = response.count(); // <1>
List<Job> jobs = response.jobs(); //<2> List<Job> jobs = response.jobs(); // <2>
//end::x-pack-ml-get-job-execute //end::x-pack-ml-get-job-execute
assertEquals(2, response.count()); assertEquals(2, response.count());
@ -266,12 +268,12 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
{ {
//tag::x-pack-delete-ml-job-request //tag::x-pack-delete-ml-job-request
DeleteJobRequest deleteJobRequest = new DeleteJobRequest("my-first-machine-learning-job"); 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); AcknowledgedResponse deleteJobResponse = client.machineLearning().deleteJob(deleteJobRequest, RequestOptions.DEFAULT);
//end::x-pack-delete-ml-job-request //end::x-pack-delete-ml-job-request
//tag::x-pack-delete-ml-job-response //tag::x-pack-delete-ml-job-response
boolean isAcknowledged = deleteJobResponse.isAcknowledged(); //<1> boolean isAcknowledged = deleteJobResponse.isAcknowledged(); // <1>
//end::x-pack-delete-ml-job-response //end::x-pack-delete-ml-job-response
} }
{ {
@ -313,13 +315,13 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
{ {
//tag::x-pack-ml-open-job-request //tag::x-pack-ml-open-job-request
OpenJobRequest openJobRequest = new OpenJobRequest("opening-my-first-machine-learning-job"); //<1> OpenJobRequest openJobRequest = new OpenJobRequest("opening-my-first-machine-learning-job"); // <1>
openJobRequest.setTimeout(TimeValue.timeValueMinutes(10)); //<2> openJobRequest.setTimeout(TimeValue.timeValueMinutes(10)); // <2>
//end::x-pack-ml-open-job-request //end::x-pack-ml-open-job-request
//tag::x-pack-ml-open-job-execute //tag::x-pack-ml-open-job-execute
OpenJobResponse openJobResponse = client.machineLearning().openJob(openJobRequest, RequestOptions.DEFAULT); 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 //end::x-pack-ml-open-job-execute
} }
@ -328,7 +330,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
ActionListener<OpenJobResponse> listener = new ActionListener<OpenJobResponse>() { ActionListener<OpenJobResponse> listener = new ActionListener<OpenJobResponse>() {
@Override @Override
public void onResponse(OpenJobResponse openJobResponse) { public void onResponse(OpenJobResponse openJobResponse) {
//<1> // <1>
} }
@Override @Override
@ -343,7 +345,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
listener = new LatchedActionListener<>(listener, latch); listener = new LatchedActionListener<>(listener, latch);
// tag::x-pack-ml-open-job-execute-async // 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 // end::x-pack-ml-open-job-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS)); assertTrue(latch.await(30L, TimeUnit.SECONDS));
@ -359,15 +361,15 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
client.machineLearning().openJob(new OpenJobRequest(job.getId()), RequestOptions.DEFAULT); client.machineLearning().openJob(new OpenJobRequest(job.getId()), RequestOptions.DEFAULT);
//tag::x-pack-ml-close-job-request //tag::x-pack-ml-close-job-request
CloseJobRequest closeJobRequest = new CloseJobRequest("closing-my-first-machine-learning-job", "otherjobs*"); //<1> CloseJobRequest closeJobRequest = new CloseJobRequest("closing-my-first-machine-learning-job", "otherjobs*"); // <1>
closeJobRequest.setForce(false); //<2> closeJobRequest.setForce(false); // <2>
closeJobRequest.setAllowNoJobs(true); //<3> closeJobRequest.setAllowNoJobs(true); // <3>
closeJobRequest.setTimeout(TimeValue.timeValueMinutes(10)); //<4> closeJobRequest.setTimeout(TimeValue.timeValueMinutes(10)); // <4>
//end::x-pack-ml-close-job-request //end::x-pack-ml-close-job-request
//tag::x-pack-ml-close-job-execute //tag::x-pack-ml-close-job-execute
CloseJobResponse closeJobResponse = client.machineLearning().closeJob(closeJobRequest, RequestOptions.DEFAULT); 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 //end::x-pack-ml-close-job-execute
} }
@ -380,7 +382,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
ActionListener<CloseJobResponse> listener = new ActionListener<CloseJobResponse>() { ActionListener<CloseJobResponse> listener = new ActionListener<CloseJobResponse>() {
@Override @Override
public void onResponse(CloseJobResponse closeJobResponse) { public void onResponse(CloseJobResponse closeJobResponse) {
//<1> // <1>
} }
@Override @Override
@ -396,7 +398,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
listener = new LatchedActionListener<>(listener, latch); listener = new LatchedActionListener<>(listener, latch);
// tag::x-pack-ml-close-job-execute-async // 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 // end::x-pack-ml-close-job-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS)); assertTrue(latch.await(30L, TimeUnit.SECONDS));
@ -427,37 +429,37 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
customSettings.put("custom-setting-1", "custom-value"); customSettings.put("custom-setting-1", "custom-value");
//tag::x-pack-ml-update-job-detector-options //tag::x-pack-ml-update-job-detector-options
JobUpdate.DetectorUpdate detectorUpdate = new JobUpdate.DetectorUpdate(0, //<1> JobUpdate.DetectorUpdate detectorUpdate = new JobUpdate.DetectorUpdate(0, // <1>
"detector description", //<2> "detector description", // <2>
detectionRules); //<3> detectionRules); // <3>
//end::x-pack-ml-update-job-detector-options //end::x-pack-ml-update-job-detector-options
//tag::x-pack-ml-update-job-options //tag::x-pack-ml-update-job-options
JobUpdate update = new JobUpdate.Builder(jobId) //<1> JobUpdate update = new JobUpdate.Builder(jobId) // <1>
.setDescription("My description") //<2> .setDescription("My description") // <2>
.setAnalysisLimits(new AnalysisLimits(1000L, null)) //<3> .setAnalysisLimits(new AnalysisLimits(1000L, null)) // <3>
.setBackgroundPersistInterval(TimeValue.timeValueHours(3)) //<4> .setBackgroundPersistInterval(TimeValue.timeValueHours(3)) // <4>
.setCategorizationFilters(Arrays.asList("categorization-filter")) //<5> .setCategorizationFilters(Arrays.asList("categorization-filter")) // <5>
.setDetectorUpdates(Arrays.asList(detectorUpdate)) //<6> .setDetectorUpdates(Arrays.asList(detectorUpdate)) // <6>
.setGroups(Arrays.asList("job-group-1")) //<7> .setGroups(Arrays.asList("job-group-1")) // <7>
.setResultsRetentionDays(10L) //<8> .setResultsRetentionDays(10L) // <8>
.setModelPlotConfig(new ModelPlotConfig(true, null)) //<9> .setModelPlotConfig(new ModelPlotConfig(true, null)) // <9>
.setModelSnapshotRetentionDays(7L) //<10> .setModelSnapshotRetentionDays(7L) // <10>
.setCustomSettings(customSettings) //<11> .setCustomSettings(customSettings) // <11>
.setRenormalizationWindowDays(3L) //<12> .setRenormalizationWindowDays(3L) // <12>
.build(); .build();
//end::x-pack-ml-update-job-options //end::x-pack-ml-update-job-options
//tag::x-pack-ml-update-job-request //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 //end::x-pack-ml-update-job-request
//tag::x-pack-ml-update-job-execute //tag::x-pack-ml-update-job-execute
PutJobResponse updateJobResponse = client.machineLearning().updateJob(updateJobRequest, RequestOptions.DEFAULT); PutJobResponse updateJobResponse = client.machineLearning().updateJob(updateJobRequest, RequestOptions.DEFAULT);
//end::x-pack-ml-update-job-execute //end::x-pack-ml-update-job-execute
//tag::x-pack-ml-update-job-response //tag::x-pack-ml-update-job-response
Job updatedJob = updateJobResponse.getResponse(); //<1> Job updatedJob = updateJobResponse.getResponse(); // <1>
//end::x-pack-ml-update-job-response //end::x-pack-ml-update-job-response
assertEquals(update.getDescription(), updatedJob.getDescription()); assertEquals(update.getDescription(), updatedJob.getDescription());
@ -467,7 +469,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
ActionListener<PutJobResponse> listener = new ActionListener<PutJobResponse>() { ActionListener<PutJobResponse> listener = new ActionListener<PutJobResponse>() {
@Override @Override
public void onResponse(PutJobResponse updateJobResponse) { public void onResponse(PutJobResponse updateJobResponse) {
//<1> // <1>
} }
@Override @Override
@ -483,7 +485,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
listener = new LatchedActionListener<>(listener, latch); listener = new LatchedActionListener<>(listener, latch);
// tag::x-pack-ml-update-job-execute-async // 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 // end::x-pack-ml-update-job-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS)); assertTrue(latch.await(30L, TimeUnit.SECONDS));
@ -590,6 +592,59 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
} }
} }
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<DatafeedConfig> 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<GetDatafeedResponse> listener = new ActionListener<GetDatafeedResponse>() {
@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 { public void testDeleteDatafeed() throws Exception {
RestHighLevelClient client = highLevelClient(); RestHighLevelClient client = highLevelClient();
@ -604,13 +659,13 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
{ {
//tag::x-pack-delete-ml-datafeed-request //tag::x-pack-delete-ml-datafeed-request
DeleteDatafeedRequest deleteDatafeedRequest = new DeleteDatafeedRequest(datafeedId); DeleteDatafeedRequest deleteDatafeedRequest = new DeleteDatafeedRequest(datafeedId);
deleteDatafeedRequest.setForce(false); //<1> deleteDatafeedRequest.setForce(false); // <1>
AcknowledgedResponse deleteDatafeedResponse = client.machineLearning().deleteDatafeed( AcknowledgedResponse deleteDatafeedResponse = client.machineLearning().deleteDatafeed(
deleteDatafeedRequest, RequestOptions.DEFAULT); deleteDatafeedRequest, RequestOptions.DEFAULT);
//end::x-pack-delete-ml-datafeed-request //end::x-pack-delete-ml-datafeed-request
//tag::x-pack-delete-ml-datafeed-response //tag::x-pack-delete-ml-datafeed-response
boolean isAcknowledged = deleteDatafeedResponse.isAcknowledged(); //<1> boolean isAcknowledged = deleteDatafeedResponse.isAcknowledged(); // <1>
//end::x-pack-delete-ml-datafeed-response //end::x-pack-delete-ml-datafeed-response
} }
@ -759,15 +814,15 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
{ {
//tag::x-pack-ml-flush-job-request //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 //end::x-pack-ml-flush-job-request
//tag::x-pack-ml-flush-job-request-options //tag::x-pack-ml-flush-job-request-options
flushJobRequest.setCalcInterim(true); //<1> flushJobRequest.setCalcInterim(true); // <1>
flushJobRequest.setAdvanceTime("2018-08-31T16:35:07+00:00"); //<2> flushJobRequest.setAdvanceTime("2018-08-31T16:35:07+00:00"); // <2>
flushJobRequest.setStart("2018-08-31T16:35:17+00:00"); //<3> flushJobRequest.setStart("2018-08-31T16:35:17+00:00"); // <3>
flushJobRequest.setEnd("2018-08-31T16:35:27+00:00"); //<4> flushJobRequest.setEnd("2018-08-31T16:35:27+00:00"); // <4>
flushJobRequest.setSkipTime("2018-08-31T16:35:00+00:00"); //<5> flushJobRequest.setSkipTime("2018-08-31T16:35:00+00:00"); // <5>
//end::x-pack-ml-flush-job-request-options //end::x-pack-ml-flush-job-request-options
//tag::x-pack-ml-flush-job-execute //tag::x-pack-ml-flush-job-execute
@ -775,8 +830,8 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
//end::x-pack-ml-flush-job-execute //end::x-pack-ml-flush-job-execute
//tag::x-pack-ml-flush-job-response //tag::x-pack-ml-flush-job-response
boolean isFlushed = flushJobResponse.isFlushed(); //<1> boolean isFlushed = flushJobResponse.isFlushed(); // <1>
Date lastFinalizedBucketEnd = flushJobResponse.getLastFinalizedBucketEnd(); //<2> Date lastFinalizedBucketEnd = flushJobResponse.getLastFinalizedBucketEnd(); // <2>
//end::x-pack-ml-flush-job-response //end::x-pack-ml-flush-job-response
} }
@ -785,7 +840,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
ActionListener<FlushJobResponse> listener = new ActionListener<FlushJobResponse>() { ActionListener<FlushJobResponse> listener = new ActionListener<FlushJobResponse>() {
@Override @Override
public void onResponse(FlushJobResponse FlushJobResponse) { public void onResponse(FlushJobResponse FlushJobResponse) {
//<1> // <1>
} }
@Override @Override
@ -801,7 +856,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
listener = new LatchedActionListener<>(listener, latch); listener = new LatchedActionListener<>(listener, latch);
// tag::x-pack-ml-flush-job-execute-async // 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 // end::x-pack-ml-flush-job-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS)); assertTrue(latch.await(30L, TimeUnit.SECONDS));
@ -839,13 +894,13 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
{ {
//tag::x-pack-ml-delete-forecast-request //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 //end::x-pack-ml-delete-forecast-request
//tag::x-pack-ml-delete-forecast-request-options //tag::x-pack-ml-delete-forecast-request-options
deleteForecastRequest.setForecastIds(forecastId); //<1> deleteForecastRequest.setForecastIds(forecastId); // <1>
deleteForecastRequest.timeout("30s"); //<2> deleteForecastRequest.timeout("30s"); // <2>
deleteForecastRequest.setAllowNoForecasts(true); //<3> deleteForecastRequest.setAllowNoForecasts(true); // <3>
//end::x-pack-ml-delete-forecast-request-options //end::x-pack-ml-delete-forecast-request-options
//tag::x-pack-ml-delete-forecast-execute //tag::x-pack-ml-delete-forecast-execute
@ -854,7 +909,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
//end::x-pack-ml-delete-forecast-execute //end::x-pack-ml-delete-forecast-execute
//tag::x-pack-ml-delete-forecast-response //tag::x-pack-ml-delete-forecast-response
boolean isAcknowledged = deleteForecastResponse.isAcknowledged(); //<1> boolean isAcknowledged = deleteForecastResponse.isAcknowledged(); // <1>
//end::x-pack-ml-delete-forecast-response //end::x-pack-ml-delete-forecast-response
} }
{ {
@ -862,7 +917,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
ActionListener<AcknowledgedResponse> listener = new ActionListener<AcknowledgedResponse>() { ActionListener<AcknowledgedResponse> listener = new ActionListener<AcknowledgedResponse>() {
@Override @Override
public void onResponse(AcknowledgedResponse DeleteForecastResponse) { public void onResponse(AcknowledgedResponse DeleteForecastResponse) {
//<1> // <1>
} }
@Override @Override
@ -879,7 +934,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
listener = new LatchedActionListener<>(listener, latch); listener = new LatchedActionListener<>(listener, latch);
// tag::x-pack-ml-delete-forecast-execute-async // 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 // end::x-pack-ml-delete-forecast-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS)); assertTrue(latch.await(30L, TimeUnit.SECONDS));
@ -897,8 +952,8 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
{ {
//tag::x-pack-ml-get-job-stats-request //tag::x-pack-ml-get-job-stats-request
GetJobStatsRequest request = new GetJobStatsRequest("get-machine-learning-job-stats1", "get-machine-learning-job-*"); //<1> GetJobStatsRequest request = new GetJobStatsRequest("get-machine-learning-job-stats1", "get-machine-learning-job-*"); // <1>
request.setAllowNoJobs(true); //<2> request.setAllowNoJobs(true); // <2>
//end::x-pack-ml-get-job-stats-request //end::x-pack-ml-get-job-stats-request
//tag::x-pack-ml-get-job-stats-execute //tag::x-pack-ml-get-job-stats-execute
@ -906,8 +961,8 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
//end::x-pack-ml-get-job-stats-execute //end::x-pack-ml-get-job-stats-execute
//tag::x-pack-ml-get-job-stats-response //tag::x-pack-ml-get-job-stats-response
long numberOfJobStats = response.count(); //<1> long numberOfJobStats = response.count(); // <1>
List<JobStats> jobStats = response.jobStats(); //<2> List<JobStats> jobStats = response.jobStats(); // <2>
//end::x-pack-ml-get-job-stats-response //end::x-pack-ml-get-job-stats-response
assertEquals(2, response.count()); assertEquals(2, response.count());
@ -964,12 +1019,12 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
{ {
//tag::x-pack-ml-forecast-job-request //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 //end::x-pack-ml-forecast-job-request
//tag::x-pack-ml-forecast-job-request-options //tag::x-pack-ml-forecast-job-request-options
forecastJobRequest.setExpiresIn(TimeValue.timeValueHours(48)); //<1> forecastJobRequest.setExpiresIn(TimeValue.timeValueHours(48)); // <1>
forecastJobRequest.setDuration(TimeValue.timeValueHours(24)); //<2> forecastJobRequest.setDuration(TimeValue.timeValueHours(24)); // <2>
//end::x-pack-ml-forecast-job-request-options //end::x-pack-ml-forecast-job-request-options
//tag::x-pack-ml-forecast-job-execute //tag::x-pack-ml-forecast-job-execute
@ -977,8 +1032,8 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
//end::x-pack-ml-forecast-job-execute //end::x-pack-ml-forecast-job-execute
//tag::x-pack-ml-forecast-job-response //tag::x-pack-ml-forecast-job-response
boolean isAcknowledged = forecastJobResponse.isAcknowledged(); //<1> boolean isAcknowledged = forecastJobResponse.isAcknowledged(); // <1>
String forecastId = forecastJobResponse.getForecastId(); //<2> String forecastId = forecastJobResponse.getForecastId(); // <2>
//end::x-pack-ml-forecast-job-response //end::x-pack-ml-forecast-job-response
assertTrue(isAcknowledged); assertTrue(isAcknowledged);
assertNotNull(forecastId); assertNotNull(forecastId);
@ -988,7 +1043,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
ActionListener<ForecastJobResponse> listener = new ActionListener<ForecastJobResponse>() { ActionListener<ForecastJobResponse> listener = new ActionListener<ForecastJobResponse>() {
@Override @Override
public void onResponse(ForecastJobResponse forecastJobResponse) { public void onResponse(ForecastJobResponse forecastJobResponse) {
//<1> // <1>
} }
@Override @Override
@ -1004,7 +1059,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
listener = new LatchedActionListener<>(listener, latch); listener = new LatchedActionListener<>(listener, latch);
// tag::x-pack-ml-forecast-job-execute-async // 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 // end::x-pack-ml-forecast-job-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS)); assertTrue(latch.await(30L, TimeUnit.SECONDS));
@ -1211,18 +1266,18 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
{ {
//tag::x-pack-ml-post-data-request //tag::x-pack-ml-post-data-request
PostDataRequest.JsonBuilder jsonBuilder = new PostDataRequest.JsonBuilder(); //<1> PostDataRequest.JsonBuilder jsonBuilder = new PostDataRequest.JsonBuilder(); // <1>
Map<String, Object> mapData = new HashMap<>(); Map<String, Object> mapData = new HashMap<>();
mapData.put("total", 109); mapData.put("total", 109);
jsonBuilder.addDoc(mapData); //<2> jsonBuilder.addDoc(mapData); // <2>
jsonBuilder.addDoc("{\"total\":1000}"); //<3> jsonBuilder.addDoc("{\"total\":1000}"); // <3>
PostDataRequest postDataRequest = new PostDataRequest("test-post-data", jsonBuilder); //<4> PostDataRequest postDataRequest = new PostDataRequest("test-post-data", jsonBuilder); // <4>
//end::x-pack-ml-post-data-request //end::x-pack-ml-post-data-request
//tag::x-pack-ml-post-data-request-options //tag::x-pack-ml-post-data-request-options
postDataRequest.setResetStart("2018-08-31T16:35:07+00:00"); //<1> postDataRequest.setResetStart("2018-08-31T16:35:07+00:00"); // <1>
postDataRequest.setResetEnd("2018-08-31T16:35:17+00:00"); //<2> postDataRequest.setResetEnd("2018-08-31T16:35:17+00:00"); // <2>
//end::x-pack-ml-post-data-request-options //end::x-pack-ml-post-data-request-options
postDataRequest.setResetEnd(null); postDataRequest.setResetEnd(null);
postDataRequest.setResetStart(null); postDataRequest.setResetStart(null);
@ -1232,7 +1287,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
//end::x-pack-ml-post-data-execute //end::x-pack-ml-post-data-execute
//tag::x-pack-ml-post-data-response //tag::x-pack-ml-post-data-response
DataCounts dataCounts = postDataResponse.getDataCounts(); //<1> DataCounts dataCounts = postDataResponse.getDataCounts(); // <1>
//end::x-pack-ml-post-data-response //end::x-pack-ml-post-data-response
assertEquals(2, dataCounts.getInputRecordCount()); assertEquals(2, dataCounts.getInputRecordCount());
@ -1242,7 +1297,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
ActionListener<PostDataResponse> listener = new ActionListener<PostDataResponse>() { ActionListener<PostDataResponse> listener = new ActionListener<PostDataResponse>() {
@Override @Override
public void onResponse(PostDataResponse postDataResponse) { public void onResponse(PostDataResponse postDataResponse) {
//<1> // <1>
} }
@Override @Override
@ -1255,14 +1310,14 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
Map<String, Object> mapData = new HashMap<>(); Map<String, Object> mapData = new HashMap<>();
mapData.put("total", 109); mapData.put("total", 109);
jsonBuilder.addDoc(mapData); 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 // Replace the empty listener by a blocking listener in test
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
listener = new LatchedActionListener<>(listener, latch); listener = new LatchedActionListener<>(listener, latch);
// tag::x-pack-ml-post-data-execute-async // 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 // end::x-pack-ml-post-data-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS)); assertTrue(latch.await(30L, TimeUnit.SECONDS));

View File

@ -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<GetDatafeedRequest> {
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<String> 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;
}
}

View File

@ -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<GetDatafeedResponse> {
@Override
protected GetDatafeedResponse createTestInstance() {
int count = randomIntBetween(1, 5);
List<DatafeedConfig.Builder> 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<String> getRandomFieldsExcludeFilter() {
return field -> !field.isEmpty();
}
@Override
protected boolean supportsUnknownFields() {
return true;
}
}

View File

@ -64,6 +64,6 @@ public class GetJobRequestTests extends AbstractXContentTestCase<GetJobRequest>
@Override @Override
protected boolean supportsUnknownFields() { protected boolean supportsUnknownFields() {
return true; return false;
} }
} }

View File

@ -44,6 +44,10 @@ public class DatafeedConfigTests extends AbstractXContentTestCase<DatafeedConfig
} }
public static DatafeedConfig createRandom() { public static DatafeedConfig createRandom() {
return createRandomBuilder().build();
}
public static DatafeedConfig.Builder createRandomBuilder() {
long bucketSpanMillis = 3600000; long bucketSpanMillis = 3600000;
DatafeedConfig.Builder builder = constructBuilder(); DatafeedConfig.Builder builder = constructBuilder();
builder.setIndices(randomStringList(1, 10)); builder.setIndices(randomStringList(1, 10));
@ -99,7 +103,7 @@ public class DatafeedConfigTests extends AbstractXContentTestCase<DatafeedConfig
if (randomBoolean()) { if (randomBoolean()) {
builder.setChunkingConfig(ChunkingConfigTests.createRandomizedChunk()); builder.setChunkingConfig(ChunkingConfigTests.createRandomizedChunk());
} }
return builder.build(); return builder;
} }
public static List<String> randomStringList(int min, int max) { public static List<String> randomStringList(int min, int max) {

View File

@ -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

View File

@ -221,6 +221,7 @@ The Java High Level REST Client supports the following Machine Learning APIs:
* <<java-rest-high-x-pack-ml-update-job>> * <<java-rest-high-x-pack-ml-update-job>>
* <<java-rest-high-x-pack-ml-get-job-stats>> * <<java-rest-high-x-pack-ml-get-job-stats>>
* <<java-rest-high-x-pack-ml-put-datafeed>> * <<java-rest-high-x-pack-ml-put-datafeed>>
* <<java-rest-high-x-pack-ml-get-datafeed>>
* <<java-rest-high-x-pack-ml-delete-datafeed>> * <<java-rest-high-x-pack-ml-delete-datafeed>>
* <<java-rest-high-x-pack-ml-forecast-job>> * <<java-rest-high-x-pack-ml-forecast-job>>
* <<java-rest-high-x-pack-ml-delete-forecast>> * <<java-rest-high-x-pack-ml-delete-forecast>>
@ -240,6 +241,7 @@ include::ml/close-job.asciidoc[]
include::ml/update-job.asciidoc[] include::ml/update-job.asciidoc[]
include::ml/flush-job.asciidoc[] include::ml/flush-job.asciidoc[]
include::ml/put-datafeed.asciidoc[] include::ml/put-datafeed.asciidoc[]
include::ml/get-datafeed.asciidoc[]
include::ml/delete-datafeed.asciidoc[] include::ml/delete-datafeed.asciidoc[]
include::ml/get-job-stats.asciidoc[] include::ml/get-job-stats.asciidoc[]
include::ml/forecast-job.asciidoc[] include::ml/forecast-job.asciidoc[]