Skip to content

Commit

Permalink
HLRC: adding machine learning delete job (#32820)
Browse files Browse the repository at this point in the history
* HLRC: adding machine learning delete job

* Fixing whitespace

* Moving docs and tests around

* Unifying ml asciidoc file naming convention
  • Loading branch information
benwtrent committed Aug 16, 2018
1 parent dbff092 commit 6333e00
Show file tree
Hide file tree
Showing 11 changed files with 412 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
package org.elasticsearch.client;

import org.elasticsearch.action.ActionListener;
import org.elasticsearch.protocol.xpack.ml.DeleteJobRequest;
import org.elasticsearch.protocol.xpack.ml.DeleteJobResponse;
import org.elasticsearch.protocol.xpack.ml.OpenJobRequest;
import org.elasticsearch.protocol.xpack.ml.OpenJobResponse;
import org.elasticsearch.protocol.xpack.ml.PutJobRequest;
Expand Down Expand Up @@ -80,6 +82,44 @@ public void putJobAsync(PutJobRequest request, RequestOptions options, ActionLis
Collections.emptySet());
}

/**
* Deletes the given Machine Learning Job
* <p>
* For additional info
* see <a href="http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-job.html">ML Delete Job documentation</a>
* </p>
* @param request the request to delete the job
* @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 DeleteJobResponse deleteJob(DeleteJobRequest request, RequestOptions options) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(request,
RequestConverters::deleteMachineLearningJob,
options,
DeleteJobResponse::fromXContent,
Collections.emptySet());
}

/**
* Deletes the given Machine Learning Job asynchronously and notifies the listener on completion
* <p>
* For additional info
* see <a href="http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-job.html">ML Delete Job documentation</a>
* </p>
* @param request the request to delete the job
* @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
*/
public void deleteJobAsync(DeleteJobRequest request, RequestOptions options, ActionListener<DeleteJobResponse> listener) {
restHighLevelClient.performRequestAsyncAndParseEntity(request,
RequestConverters::deleteMachineLearningJob,
options,
DeleteJobResponse::fromXContent,
listener,
Collections.emptySet());
}

/**
* Opens a Machine Learning Job.
* When you open a new job, it starts with an empty model.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
import org.elasticsearch.protocol.xpack.license.GetLicenseRequest;
import org.elasticsearch.protocol.xpack.license.PutLicenseRequest;
import org.elasticsearch.protocol.xpack.migration.IndexUpgradeInfoRequest;
import org.elasticsearch.protocol.xpack.ml.DeleteJobRequest;
import org.elasticsearch.protocol.xpack.ml.OpenJobRequest;
import org.elasticsearch.protocol.xpack.ml.PutJobRequest;
import org.elasticsearch.protocol.xpack.watcher.DeleteWatchRequest;
Expand Down Expand Up @@ -1222,6 +1223,21 @@ static Request putMachineLearningJob(PutJobRequest putJobRequest) throws IOExcep
return request;
}

static Request deleteMachineLearningJob(DeleteJobRequest deleteJobRequest) {
String endpoint = new EndpointBuilder()
.addPathPartAsIs("_xpack")
.addPathPartAsIs("ml")
.addPathPartAsIs("anomaly_detectors")
.addPathPart(deleteJobRequest.getJobId())
.build();
Request request = new Request(HttpDelete.METHOD_NAME, endpoint);

Params params = new Params(request);
params.putParam("force", Boolean.toString(deleteJobRequest.isForce()));

return request;
}

static Request machineLearningOpenJob(OpenJobRequest openJobRequest) throws IOException {
String endpoint = new EndpointBuilder()
.addPathPartAsIs("_xpack")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

import com.carrotsearch.randomizedtesting.generators.CodepointSetGenerator;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.protocol.xpack.ml.DeleteJobRequest;
import org.elasticsearch.protocol.xpack.ml.DeleteJobResponse;
import org.elasticsearch.protocol.xpack.ml.OpenJobRequest;
import org.elasticsearch.protocol.xpack.ml.OpenJobResponse;
import org.elasticsearch.protocol.xpack.ml.PutJobRequest;
Expand Down Expand Up @@ -48,6 +50,19 @@ public void testPutJob() throws Exception {
assertThat(createdJob.getJobType(), is(Job.ANOMALY_DETECTOR_JOB_TYPE));
}

public void testDeleteJob() throws Exception {
String jobId = randomValidJobId();
Job job = buildJob(jobId);
MachineLearningClient machineLearningClient = highLevelClient().machineLearning();
machineLearningClient.putJob(new PutJobRequest(job), RequestOptions.DEFAULT);

DeleteJobResponse response = execute(new DeleteJobRequest(jobId),
machineLearningClient::deleteJob,
machineLearningClient::deleteJobAsync);

assertTrue(response.isAcknowledged());
}

public void testOpenJob() throws Exception {
String jobId = randomValidJobId();
Job job = buildJob(jobId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
import org.elasticsearch.index.rankeval.RestRankEvalAction;
import org.elasticsearch.protocol.xpack.XPackInfoRequest;
import org.elasticsearch.protocol.xpack.migration.IndexUpgradeInfoRequest;
import org.elasticsearch.protocol.xpack.ml.DeleteJobRequest;
import org.elasticsearch.protocol.xpack.ml.OpenJobRequest;
import org.elasticsearch.protocol.xpack.watcher.DeleteWatchRequest;
import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
Expand Down Expand Up @@ -2645,6 +2646,20 @@ public void testXPackDeleteWatch() {
assertThat(request.getEntity(), nullValue());
}

public void testDeleteMachineLearningJob() {
String jobId = randomAlphaOfLength(10);
DeleteJobRequest deleteJobRequest = new DeleteJobRequest(jobId);

Request request = RequestConverters.deleteMachineLearningJob(deleteJobRequest);
assertEquals(HttpDelete.METHOD_NAME, request.getMethod());
assertEquals("/_xpack/ml/anomaly_detectors/" + jobId, request.getEndpoint());
assertEquals(Boolean.toString(false), request.getParameters().get("force"));

deleteJobRequest.setForce(true);
request = RequestConverters.deleteMachineLearningJob(deleteJobRequest);
assertEquals(Boolean.toString(true), request.getParameters().get("force"));
}

public void testPostMachineLearningOpenJob() throws Exception {
String jobId = "some-job-id";
OpenJobRequest openJobRequest = new OpenJobRequest(jobId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.protocol.xpack.ml.DeleteJobRequest;
import org.elasticsearch.protocol.xpack.ml.DeleteJobResponse;
import org.elasticsearch.protocol.xpack.ml.OpenJobRequest;
import org.elasticsearch.protocol.xpack.ml.OpenJobResponse;
import org.elasticsearch.protocol.xpack.ml.PutJobRequest;
Expand Down Expand Up @@ -122,6 +124,56 @@ public void onFailure(Exception e) {
}
}

public void testDeleteJob() throws Exception {
RestHighLevelClient client = highLevelClient();

String jobId = "my-first-machine-learning-job";

Job job = MachineLearningIT.buildJob(jobId);
client.machineLearning().putJob(new PutJobRequest(job), RequestOptions.DEFAULT);

Job secondJob = MachineLearningIT.buildJob("my-second-machine-learning-job");
client.machineLearning().putJob(new PutJobRequest(secondJob), RequestOptions.DEFAULT);

{
//tag::x-pack-delete-ml-job-request
DeleteJobRequest deleteJobRequest = new DeleteJobRequest("my-first-machine-learning-job");
deleteJobRequest.setForce(false); //<1>
DeleteJobResponse deleteJobResponse = client.machineLearning().deleteJob(deleteJobRequest, RequestOptions.DEFAULT);
//end::x-pack-delete-ml-job-request

//tag::x-pack-delete-ml-job-response
boolean isAcknowledged = deleteJobResponse.isAcknowledged(); //<1>
//end::x-pack-delete-ml-job-response
}
{
//tag::x-pack-delete-ml-job-request-listener
ActionListener<DeleteJobResponse> listener = new ActionListener<DeleteJobResponse>() {
@Override
public void onResponse(DeleteJobResponse deleteJobResponse) {
// <1>
}

@Override
public void onFailure(Exception e) {
// <2>
}
};
//end::x-pack-delete-ml-job-request-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-delete-ml-job-request-async
DeleteJobRequest deleteJobRequest = new DeleteJobRequest("my-second-machine-learning-job");
client.machineLearning().deleteJobAsync(deleteJobRequest, RequestOptions.DEFAULT, listener); // <1>
//end::x-pack-delete-ml-job-request-async

assertTrue(latch.await(30L, TimeUnit.SECONDS));
}
}

public void testOpenJob() throws Exception {
RestHighLevelClient client = highLevelClient();

Expand All @@ -143,7 +195,6 @@ public void testOpenJob() throws Exception {
//end::x-pack-ml-open-job-execute

}

{
//tag::x-pack-ml-open-job-listener
ActionListener<OpenJobResponse> listener = new ActionListener<OpenJobResponse>() {
Expand All @@ -154,7 +205,7 @@ public void onResponse(OpenJobResponse openJobResponse) {

@Override
public void onFailure(Exception e) {
//<2>
// <2>
}
};
//end::x-pack-ml-open-job-listener
Expand All @@ -169,6 +220,5 @@ public void onFailure(Exception e) {

assertTrue(latch.await(30L, TimeUnit.SECONDS));
}

}
}
49 changes: 49 additions & 0 deletions docs/java-rest/high-level/ml/delete-job.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
[[java-rest-high-x-pack-ml-delete-job]]
=== Delete Job API

[[java-rest-high-x-pack-machine-learning-delete-job-request]]
==== Delete Job Request

A `DeleteJobRequest` object requires a non-null `jobId` and can optionally set `force`.
Can be executed as follows:

["source","java",subs="attributes,callouts,macros"]
---------------------------------------------------
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-delete-ml-job-request]
---------------------------------------------------
<1> Use to forcefully delete an opened job;
this method is quicker than closing and deleting the job.
Defaults to `false`

[[java-rest-high-x-pack-machine-learning-delete-job-response]]
==== Delete Job Response

The returned `DeleteJobResponse` object indicates the acknowledgement of the request:
["source","java",subs="attributes,callouts,macros"]
---------------------------------------------------
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-delete-ml-job-response]
---------------------------------------------------
<1> `isAcknowledged` was the deletion request acknowledged or not

[[java-rest-high-x-pack-machine-learning-delete-job-async]]
==== Delete Job Asynchronously

This request can also be made asynchronously.
["source","java",subs="attributes,callouts,macros"]
---------------------------------------------------
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-delete-ml-job-request-async]
---------------------------------------------------
<1> The `DeleteJobRequest` to execute and the `ActionListener` to alert on completion or error.

The deletion request returns immediately. Once the request is completed, the `ActionListener` is
called back using the `onResponse` or `onFailure`. The latter indicates some failure occurred when
making the request.

A typical listener for a `DeleteJobRequest` could be defined as follows:

["source","java",subs="attributes,callouts,macros"]
---------------------------------------------------
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-delete-ml-job-request-listener]
---------------------------------------------------
<1> The action to be taken when it is completed
<2> What to do when a failure occurs
2 changes: 2 additions & 0 deletions docs/java-rest/high-level/supported-apis.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,11 @@ include::licensing/delete-license.asciidoc[]
The Java High Level REST Client supports the following Machine Learning APIs:

* <<java-rest-high-x-pack-ml-put-job>>
* <<java-rest-high-x-pack-ml-delete-job>>
* <<java-rest-high-x-pack-ml-open-job>>

include::ml/put-job.asciidoc[]
include::ml/delete-job.asciidoc[]
include::ml/open-job.asciidoc[]

== Migration APIs
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* 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.protocol.xpack.ml;

import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;

import java.util.Objects;

public class DeleteJobRequest extends ActionRequest {

private String jobId;
private boolean force;

public DeleteJobRequest(String jobId) {
this.jobId = Objects.requireNonNull(jobId, "[job_id] must not be null");
}

public String getJobId() {
return jobId;
}

public void setJobId(String jobId) {
this.jobId = Objects.requireNonNull(jobId, "[job_id] must not be null");
}

public boolean isForce() {
return force;
}

public void setForce(boolean force) {
this.force = force;
}

@Override
public ActionRequestValidationException validate() {
return null;
}

@Override
public int hashCode() {
return Objects.hash(jobId, force);
}

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

if (obj == null || obj.getClass() != getClass()) {
return false;
}

DeleteJobRequest other = (DeleteJobRequest) obj;
return Objects.equals(jobId, other.jobId) && Objects.equals(force, other.force);
}

}
Loading

0 comments on commit 6333e00

Please sign in to comment.