Skip to content

Commit

Permalink
Introduce DataFrameAnalyticsConfig update API (#58302)
Browse files Browse the repository at this point in the history
  • Loading branch information
przemekwitek authored Jun 29, 2020
1 parent 38185e5 commit 3953de4
Show file tree
Hide file tree
Showing 32 changed files with 1,919 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
import org.elasticsearch.client.ml.StartDatafeedRequest;
import org.elasticsearch.client.ml.StopDataFrameAnalyticsRequest;
import org.elasticsearch.client.ml.StopDatafeedRequest;
import org.elasticsearch.client.ml.UpdateDataFrameAnalyticsRequest;
import org.elasticsearch.client.ml.UpdateDatafeedRequest;
import org.elasticsearch.client.ml.UpdateFilterRequest;
import org.elasticsearch.client.ml.UpdateJobRequest;
Expand Down Expand Up @@ -616,6 +617,17 @@ static Request putDataFrameAnalytics(PutDataFrameAnalyticsRequest putRequest) th
return request;
}

static Request updateDataFrameAnalytics(UpdateDataFrameAnalyticsRequest updateRequest) throws IOException {
String endpoint = new EndpointBuilder()
.addPathPartAsIs("_ml", "data_frame", "analytics")
.addPathPart(updateRequest.getUpdate().getId())
.addPathPartAsIs("_update")
.build();
Request request = new Request(HttpPost.METHOD_NAME, endpoint);
request.setEntity(createEntity(updateRequest, REQUEST_BODY_CONTENT_TYPE));
return request;
}

static Request getDataFrameAnalytics(GetDataFrameAnalyticsRequest getRequest) {
String endpoint = new EndpointBuilder()
.addPathPartAsIs("_ml", "data_frame", "analytics")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
import org.elasticsearch.client.ml.StopDataFrameAnalyticsResponse;
import org.elasticsearch.client.ml.StopDatafeedRequest;
import org.elasticsearch.client.ml.StopDatafeedResponse;
import org.elasticsearch.client.ml.UpdateDataFrameAnalyticsRequest;
import org.elasticsearch.client.ml.UpdateDatafeedRequest;
import org.elasticsearch.client.ml.UpdateFilterRequest;
import org.elasticsearch.client.ml.UpdateJobRequest;
Expand Down Expand Up @@ -2042,6 +2043,52 @@ public Cancellable putDataFrameAnalyticsAsync(PutDataFrameAnalyticsRequest reque
Collections.emptySet());
}

/**
* Updates a Data Frame Analytics config
* <p>
* For additional info
* see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/update-dfanalytics.html">
* PUT Data Frame Analytics documentation</a>
*
* @param request The {@link UpdateDataFrameAnalyticsRequest} containing the
* {@link org.elasticsearch.client.ml.dataframe.DataFrameAnalyticsConfigUpdate}
* @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @return The {@link PutDataFrameAnalyticsResponse} containing the updated
* {@link org.elasticsearch.client.ml.dataframe.DataFrameAnalyticsConfig}
* @throws IOException when there is a serialization issue sending the request or receiving the response
*/
public PutDataFrameAnalyticsResponse updateDataFrameAnalytics(UpdateDataFrameAnalyticsRequest request,
RequestOptions options) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(request,
MLRequestConverters::updateDataFrameAnalytics,
options,
PutDataFrameAnalyticsResponse::fromXContent,
Collections.emptySet());
}

/**
* Updates a Data Frame Analytics config asynchronously and notifies listener upon completion
* <p>
* For additional info
* see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/update-dfanalytics.html">
* Update Data Frame Analytics documentation</a>
*
* @param request The {@link UpdateDataFrameAnalyticsRequest} containing the
* {@link org.elasticsearch.client.ml.dataframe.DataFrameAnalyticsConfigUpdate}
* @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
* @return cancellable that may be used to cancel the request
*/
public Cancellable updateDataFrameAnalyticsAsync(UpdateDataFrameAnalyticsRequest request, RequestOptions options,
ActionListener<PutDataFrameAnalyticsResponse> listener) {
return restHighLevelClient.performRequestAsyncAndParseEntity(request,
MLRequestConverters::updateDataFrameAnalytics,
options,
PutDataFrameAnalyticsResponse::fromXContent,
listener,
Collections.emptySet());
}

/**
* Gets a single or multiple Data Frame Analytics configs
* <p>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* 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.Validatable;
import org.elasticsearch.client.ValidationException;
import org.elasticsearch.client.ml.dataframe.DataFrameAnalyticsConfigUpdate;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;

import java.io.IOException;
import java.util.Objects;
import java.util.Optional;

public class UpdateDataFrameAnalyticsRequest implements ToXContentObject, Validatable {

private final DataFrameAnalyticsConfigUpdate update;

public UpdateDataFrameAnalyticsRequest(DataFrameAnalyticsConfigUpdate update) {
this.update = update;
}

public DataFrameAnalyticsConfigUpdate getUpdate() {
return update;
}

@Override
public Optional<ValidationException> validate() {
if (update == null) {
return Optional.of(ValidationException.withError("update requires a non-null data frame analytics config update"));
}
return Optional.empty();
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return update.toXContent(builder, params);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

UpdateDataFrameAnalyticsRequest other = (UpdateDataFrameAnalyticsRequest) o;
return Objects.equals(update, other.update);
}

@Override
public int hashCode() {
return Objects.hash(update);
}

@Override
public String toString() {
return Strings.toString(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,16 @@ public static Builder builder() {
return new Builder();
}

private static final ParseField ID = new ParseField("id");
private static final ParseField DESCRIPTION = new ParseField("description");
private static final ParseField SOURCE = new ParseField("source");
private static final ParseField DEST = new ParseField("dest");
private static final ParseField ANALYSIS = new ParseField("analysis");
private static final ParseField ANALYZED_FIELDS = new ParseField("analyzed_fields");
private static final ParseField MODEL_MEMORY_LIMIT = new ParseField("model_memory_limit");
private static final ParseField CREATE_TIME = new ParseField("create_time");
private static final ParseField VERSION = new ParseField("version");
private static final ParseField ALLOW_LAZY_START = new ParseField("allow_lazy_start");
static final ParseField ID = new ParseField("id");
static final ParseField DESCRIPTION = new ParseField("description");
static final ParseField SOURCE = new ParseField("source");
static final ParseField DEST = new ParseField("dest");
static final ParseField ANALYSIS = new ParseField("analysis");
static final ParseField ANALYZED_FIELDS = new ParseField("analyzed_fields");
static final ParseField MODEL_MEMORY_LIMIT = new ParseField("model_memory_limit");
static final ParseField CREATE_TIME = new ParseField("create_time");
static final ParseField VERSION = new ParseField("version");
static final ParseField ALLOW_LAZY_START = new ParseField("allow_lazy_start");

private static final ObjectParser<Builder, Void> PARSER = new ObjectParser<>("data_frame_analytics_config", true, Builder::new);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
* 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.dataframe;

import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;

import java.io.IOException;
import java.util.Objects;

import static org.elasticsearch.common.xcontent.ObjectParser.ValueType.VALUE;

public class DataFrameAnalyticsConfigUpdate implements ToXContentObject {

public static DataFrameAnalyticsConfigUpdate fromXContent(XContentParser parser) {
return PARSER.apply(parser, null).build();
}

public static Builder builder() {
return new Builder();
}

public static final ObjectParser<Builder, Void> PARSER = new ObjectParser<>("data_frame_analytics_config_update", true, Builder::new);

static {
PARSER.declareString(Builder::setId, DataFrameAnalyticsConfig.ID);
PARSER.declareStringOrNull(Builder::setDescription, DataFrameAnalyticsConfig.DESCRIPTION);
PARSER.declareField(
Builder::setModelMemoryLimit,
(p, c) -> ByteSizeValue.parseBytesSizeValue(p.text(), DataFrameAnalyticsConfig.MODEL_MEMORY_LIMIT.getPreferredName()),
DataFrameAnalyticsConfig.MODEL_MEMORY_LIMIT,
VALUE);
PARSER.declareBoolean(Builder::setAllowLazyStart, DataFrameAnalyticsConfig.ALLOW_LAZY_START);

}

private final String id;
private final String description;
private final ByteSizeValue modelMemoryLimit;
private final Boolean allowLazyStart;

private DataFrameAnalyticsConfigUpdate(String id,
@Nullable String description,
@Nullable ByteSizeValue modelMemoryLimit,
@Nullable Boolean allowLazyStart) {
this.id = id;
this.description = description;
this.modelMemoryLimit = modelMemoryLimit;
this.allowLazyStart = allowLazyStart;
}

public String getId() {
return id;
}

public String getDescription() {
return description;
}

public ByteSizeValue getModelMemoryLimit() {
return modelMemoryLimit;
}

public Boolean isAllowLazyStart() {
return allowLazyStart;
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field(DataFrameAnalyticsConfig.ID.getPreferredName(), id);
if (description != null) {
builder.field(DataFrameAnalyticsConfig.DESCRIPTION.getPreferredName(), description);
}
if (modelMemoryLimit != null) {
builder.field(DataFrameAnalyticsConfig.MODEL_MEMORY_LIMIT.getPreferredName(), modelMemoryLimit.getStringRep());
}
if (allowLazyStart != null) {
builder.field(DataFrameAnalyticsConfig.ALLOW_LAZY_START.getPreferredName(), allowLazyStart);
}
builder.endObject();
return builder;
}

@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}

if (other instanceof DataFrameAnalyticsConfigUpdate == false) {
return false;
}

DataFrameAnalyticsConfigUpdate that = (DataFrameAnalyticsConfigUpdate) other;

return Objects.equals(this.id, that.id)
&& Objects.equals(this.description, that.description)
&& Objects.equals(this.modelMemoryLimit, that.modelMemoryLimit)
&& Objects.equals(this.allowLazyStart, that.allowLazyStart);
}

@Override
public int hashCode() {
return Objects.hash(id, description, modelMemoryLimit, allowLazyStart);
}

public static class Builder {

private String id;
private String description;
private ByteSizeValue modelMemoryLimit;
private Boolean allowLazyStart;

private Builder() {}

public String getId() {
return id;
}

public Builder setId(String id) {
this.id = id;
return this;
}

public Builder setDescription(String description) {
this.description = description;
return this;
}

public Builder setModelMemoryLimit(ByteSizeValue modelMemoryLimit) {
this.modelMemoryLimit = modelMemoryLimit;
return this;
}

public Builder setAllowLazyStart(Boolean allowLazyStart) {
this.allowLazyStart = allowLazyStart;
return this;
}

public DataFrameAnalyticsConfigUpdate build() {
return new DataFrameAnalyticsConfigUpdate(id, description, modelMemoryLimit, allowLazyStart);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
import org.elasticsearch.client.ml.StartDatafeedRequestTests;
import org.elasticsearch.client.ml.StopDataFrameAnalyticsRequest;
import org.elasticsearch.client.ml.StopDatafeedRequest;
import org.elasticsearch.client.ml.UpdateDataFrameAnalyticsRequest;
import org.elasticsearch.client.ml.UpdateFilterRequest;
import org.elasticsearch.client.ml.UpdateJobRequest;
import org.elasticsearch.client.ml.UpdateModelSnapshotRequest;
Expand All @@ -90,6 +91,7 @@
import org.elasticsearch.client.ml.datafeed.DatafeedConfig;
import org.elasticsearch.client.ml.datafeed.DatafeedConfigTests;
import org.elasticsearch.client.ml.dataframe.DataFrameAnalyticsConfig;
import org.elasticsearch.client.ml.dataframe.DataFrameAnalyticsConfigUpdate;
import org.elasticsearch.client.ml.dataframe.MlDataFrameAnalysisNamedXContentProvider;
import org.elasticsearch.client.ml.dataframe.evaluation.MlEvaluationNamedXContentProvider;
import org.elasticsearch.client.ml.dataframe.stats.AnalysisStatsNamedXContentProvider;
Expand Down Expand Up @@ -127,6 +129,7 @@
import java.util.Map;

import static org.elasticsearch.client.ml.dataframe.DataFrameAnalyticsConfigTests.randomDataFrameAnalyticsConfig;
import static org.elasticsearch.client.ml.dataframe.DataFrameAnalyticsConfigUpdateTests.randomDataFrameAnalyticsConfigUpdate;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasEntry;
Expand Down Expand Up @@ -740,6 +743,17 @@ public void testPutDataFrameAnalytics() throws IOException {
}
}

public void testUpdateDataFrameAnalytics() throws IOException {
UpdateDataFrameAnalyticsRequest updateRequest = new UpdateDataFrameAnalyticsRequest(randomDataFrameAnalyticsConfigUpdate());
Request request = MLRequestConverters.updateDataFrameAnalytics(updateRequest);
assertEquals(HttpPost.METHOD_NAME, request.getMethod());
assertEquals("/_ml/data_frame/analytics/" + updateRequest.getUpdate().getId() + "/_update", request.getEndpoint());
try (XContentParser parser = createParser(JsonXContent.jsonXContent, request.getEntity().getContent())) {
DataFrameAnalyticsConfigUpdate parsedUpdate = DataFrameAnalyticsConfigUpdate.fromXContent(parser);
assertThat(parsedUpdate, equalTo(updateRequest.getUpdate()));
}
}

public void testGetDataFrameAnalytics() {
String configId1 = randomAlphaOfLength(10);
String configId2 = randomAlphaOfLength(10);
Expand Down
Loading

0 comments on commit 3953de4

Please sign in to comment.