[7.x] [ML][Inference][HLRC] Delete trained model API (#49567) (#49585)

* [ML][Inference][HLRC] Delete trained model API (#49567)

* fixing for backport
This commit is contained in:
Benjamin Trent 2019-11-26 08:27:08 -05:00 committed by GitHub
parent b0cb7bf229
commit 26a8ca00db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 278 additions and 0 deletions

View File

@ -29,6 +29,7 @@ import org.apache.lucene.util.BytesRef;
import org.elasticsearch.client.RequestConverters.EndpointBuilder;
import org.elasticsearch.client.core.PageParams;
import org.elasticsearch.client.ml.CloseJobRequest;
import org.elasticsearch.client.ml.DeleteTrainedModelRequest;
import org.elasticsearch.client.ml.ExplainDataFrameAnalyticsRequest;
import org.elasticsearch.client.ml.DeleteCalendarEventRequest;
import org.elasticsearch.client.ml.DeleteCalendarJobRequest;
@ -748,6 +749,14 @@ final class MLRequestConverters {
return request;
}
static Request deleteTrainedModel(DeleteTrainedModelRequest deleteRequest) {
String endpoint = new EndpointBuilder()
.addPathPartAsIs("_ml", "inference")
.addPathPart(deleteRequest.getId())
.build();
return new Request(HttpDelete.METHOD_NAME, endpoint);
}
static Request putFilter(PutFilterRequest putFilterRequest) throws IOException {
String endpoint = new EndpointBuilder()
.addPathPartAsIs("_ml")

View File

@ -22,6 +22,7 @@ import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.ml.CloseJobRequest;
import org.elasticsearch.client.ml.CloseJobResponse;
import org.elasticsearch.client.ml.DeleteTrainedModelRequest;
import org.elasticsearch.client.ml.ExplainDataFrameAnalyticsRequest;
import org.elasticsearch.client.ml.ExplainDataFrameAnalyticsResponse;
import org.elasticsearch.client.ml.DeleteCalendarEventRequest;
@ -2337,4 +2338,46 @@ public final class MachineLearningClient {
Collections.emptySet());
}
/**
* Deletes the given Trained Model
* <p>
* For additional info
* see <a href="TODO">
* DELETE Trained Model documentation</a>
*
* @param request The {@link DeleteTrainedModelRequest}
* @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @return action acknowledgement
* @throws IOException when there is a serialization issue sending the request or receiving the response
*/
public AcknowledgedResponse deleteTrainedModel(DeleteTrainedModelRequest request, RequestOptions options) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(request,
MLRequestConverters::deleteTrainedModel,
options,
AcknowledgedResponse::fromXContent,
Collections.emptySet());
}
/**
* Deletes the given Trained Model asynchronously and notifies listener upon completion
* <p>
* For additional info
* see <a href="TODO">
* DELETE Trained Model documentation</a>
*
* @param request The {@link DeleteTrainedModelRequest}
* @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 deleteTrainedModelAsync(DeleteTrainedModelRequest request,
RequestOptions options,
ActionListener<AcknowledgedResponse> listener) {
return restHighLevelClient.performRequestAsyncAndParseEntity(request,
MLRequestConverters::deleteTrainedModel,
options,
AcknowledgedResponse::fromXContent,
listener,
Collections.emptySet());
}
}

View File

@ -0,0 +1,64 @@
/*
* 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 java.util.Objects;
import java.util.Optional;
/**
* Request to delete a data frame analytics config
*/
public class DeleteTrainedModelRequest implements Validatable {
private final String id;
public DeleteTrainedModelRequest(String id) {
this.id = id;
}
public String getId() {
return id;
}
@Override
public Optional<ValidationException> validate() {
if (id == null) {
return Optional.of(ValidationException.withError("trained model id must not be null"));
}
return Optional.empty();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DeleteTrainedModelRequest other = (DeleteTrainedModelRequest) o;
return Objects.equals(id, other.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}

View File

@ -25,6 +25,7 @@ import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.elasticsearch.client.core.PageParams;
import org.elasticsearch.client.ml.CloseJobRequest;
import org.elasticsearch.client.ml.DeleteTrainedModelRequest;
import org.elasticsearch.client.ml.ExplainDataFrameAnalyticsRequest;
import org.elasticsearch.client.ml.DeleteCalendarEventRequest;
import org.elasticsearch.client.ml.DeleteCalendarJobRequest;
@ -836,6 +837,14 @@ public class MLRequestConvertersTests extends ESTestCase {
assertNull(request.getEntity());
}
public void testDeleteTrainedModel() {
DeleteTrainedModelRequest deleteRequest = new DeleteTrainedModelRequest(randomAlphaOfLength(10));
Request request = MLRequestConverters.deleteTrainedModel(deleteRequest);
assertEquals(HttpDelete.METHOD_NAME, request.getMethod());
assertEquals("/_ml/inference/" + deleteRequest.getId(), request.getEndpoint());
assertNull(request.getEntity());
}
public void testPutFilter() throws IOException {
MlFilter filter = MlFilterTests.createRandomBuilder("foo").build();
PutFilterRequest putFilterRequest = new PutFilterRequest(filter);

View File

@ -32,6 +32,7 @@ import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.ml.CloseJobRequest;
import org.elasticsearch.client.ml.CloseJobResponse;
import org.elasticsearch.client.ml.DeleteTrainedModelRequest;
import org.elasticsearch.client.ml.ExplainDataFrameAnalyticsRequest;
import org.elasticsearch.client.ml.ExplainDataFrameAnalyticsResponse;
import org.elasticsearch.client.ml.DeleteCalendarEventRequest;
@ -2122,6 +2123,33 @@ public class MachineLearningIT extends ESRestHighLevelClientTestCase {
}
}
public void testDeleteTrainedModel() throws Exception {
MachineLearningClient machineLearningClient = highLevelClient().machineLearning();
String modelId = "delete-trained-model-test";
putTrainedModel(modelId);
GetTrainedModelsResponse getTrainedModelsResponse = execute(
new GetTrainedModelsRequest(modelId + "*").setIncludeDefinition(false).setAllowNoMatch(true),
machineLearningClient::getTrainedModels,
machineLearningClient::getTrainedModelsAsync);
assertThat(getTrainedModelsResponse.getCount(), equalTo(1L));
assertThat(getTrainedModelsResponse.getTrainedModels(), hasSize(1));
AcknowledgedResponse deleteTrainedModelResponse = execute(
new DeleteTrainedModelRequest(modelId),
machineLearningClient::deleteTrainedModel, machineLearningClient::deleteTrainedModelAsync);
assertTrue(deleteTrainedModelResponse.isAcknowledged());
getTrainedModelsResponse = execute(
new GetTrainedModelsRequest(modelId + "*").setIncludeDefinition(false).setAllowNoMatch(true),
machineLearningClient::getTrainedModels,
machineLearningClient::getTrainedModelsAsync);
assertThat(getTrainedModelsResponse.getCount(), equalTo(0L));
assertThat(getTrainedModelsResponse.getTrainedModels(), hasSize(0));
}
public void testPutFilter() throws Exception {
String filterId = "filter-job-test";
MlFilter mlFilter = MlFilter.builder(filterId)

View File

@ -36,6 +36,7 @@ import org.elasticsearch.client.core.PageParams;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.ml.CloseJobRequest;
import org.elasticsearch.client.ml.CloseJobResponse;
import org.elasticsearch.client.ml.DeleteTrainedModelRequest;
import org.elasticsearch.client.ml.ExplainDataFrameAnalyticsRequest;
import org.elasticsearch.client.ml.ExplainDataFrameAnalyticsResponse;
import org.elasticsearch.client.ml.DeleteCalendarEventRequest;
@ -3592,6 +3593,53 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
}
}
public void testDeleteTrainedModel() throws Exception {
RestHighLevelClient client = highLevelClient();
{
putTrainedModel("my-trained-model");
// tag::delete-trained-model-request
DeleteTrainedModelRequest request = new DeleteTrainedModelRequest("my-trained-model"); // <1>
// end::delete-trained-model-request
// tag::delete-trained-model-execute
AcknowledgedResponse response = client.machineLearning().deleteTrainedModel(request, RequestOptions.DEFAULT);
// end::delete-trained-model-execute
// tag::delete-trained-model-response
boolean deleted = response.isAcknowledged();
// end::delete-trained-model-response
assertThat(deleted, is(true));
}
{
putTrainedModel("my-trained-model");
DeleteTrainedModelRequest request = new DeleteTrainedModelRequest("my-trained-model");
// tag::delete-trained-model-execute-listener
ActionListener<AcknowledgedResponse> listener = new ActionListener<AcknowledgedResponse>() {
@Override
public void onResponse(AcknowledgedResponse response) {
// <1>
}
@Override
public void onFailure(Exception e) {
// <2>
}
};
// end::delete-trained-model-execute-listener
// Replace the empty listener by a blocking listener in test
CountDownLatch latch = new CountDownLatch(1);
listener = new LatchedActionListener<>(listener, latch);
// tag::delete-trained-model-execute-async
client.machineLearning().deleteTrainedModelAsync(request, RequestOptions.DEFAULT, listener); // <1>
// end::delete-trained-model-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS));
}
}
public void testCreateFilter() throws Exception {
RestHighLevelClient client = highLevelClient();

View File

@ -0,0 +1,39 @@
/*
* 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.test.ESTestCase;
import java.util.Optional;
import static org.hamcrest.Matchers.containsString;
public class DeleteTrainedModelRequestTests extends ESTestCase {
public void testValidate_Ok() {
assertEquals(Optional.empty(), new DeleteTrainedModelRequest("valid-id").validate());
assertEquals(Optional.empty(), new DeleteTrainedModelRequest("").validate());
}
public void testValidate_Failure() {
assertThat(new DeleteTrainedModelRequest(null).validate().get().getMessage(),
containsString("trained model id must not be null"));
}
}

View File

@ -0,0 +1,36 @@
--
:api: delete-trained-model
:request: DeleteTrainedModelRequest
:response: AcknowledgedResponse
--
[role="xpack"]
[id="{upid}-{api}"]
=== Delete Trained Model API
experimental[]
Deletes a previously saved Trained Model.
The API accepts a +{request}+ object and returns a +{response}+.
[id="{upid}-{api}-request"]
==== Delete Trained Model request
A +{request}+ requires a valid Trained Model ID.
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests-file}[{api}-request]
--------------------------------------------------
<1> Constructing a new DELETE request referencing an existing Trained Model
include::../execution.asciidoc[]
[id="{upid}-{api}-response"]
==== Response
The returned +{response}+ object acknowledges the Trained Model deletion.
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests-file}[{api}-response]
--------------------------------------------------

View File

@ -302,6 +302,7 @@ The Java High Level REST Client supports the following Machine Learning APIs:
* <<{upid}-evaluate-data-frame>>
* <<{upid}-explain-data-frame-analytics>>
* <<{upid}-get-trained-models>>
* <<{upid}-delete-trained-model>>
* <<{upid}-put-filter>>
* <<{upid}-get-filters>>
* <<{upid}-update-filter>>
@ -355,6 +356,7 @@ include::ml/stop-data-frame-analytics.asciidoc[]
include::ml/evaluate-data-frame.asciidoc[]
include::ml/explain-data-frame-analytics.asciidoc[]
include::ml/get-trained-models.asciidoc[]
include::ml/delete-trained-model.asciidoc[]
include::ml/put-filter.asciidoc[]
include::ml/get-filters.asciidoc[]
include::ml/update-filter.asciidoc[]