From 68c0a295787f0f0549b01738740372c0abe4e3a0 Mon Sep 17 00:00:00 2001 From: David Kyle Date: Wed, 19 Sep 2018 10:20:21 +0100 Subject: [PATCH] HLRC: Delete ML calendar (#33775) --- .../client/MLRequestConverters.java | 12 ++++ .../client/MachineLearningClient.java | 41 ++++++++++++ .../client/ml/DeleteCalendarRequest.java | 65 +++++++++++++++++++ .../client/MLRequestConvertersTests.java | 8 +++ .../client/MachineLearningIT.java | 19 ++++++ .../MlClientDocumentationIT.java | 47 ++++++++++++++ .../client/ml/DeleteCalendarRequestTests.java | 43 ++++++++++++ .../high-level/ml/delete-calendar.asciidoc | 59 +++++++++++++++++ .../high-level/supported-apis.asciidoc | 2 + 9 files changed, 296 insertions(+) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/ml/DeleteCalendarRequest.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/ml/DeleteCalendarRequestTests.java create mode 100644 docs/java-rest/high-level/ml/delete-calendar.asciidoc diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/MLRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/MLRequestConverters.java index bc2ff7b17d57b..ed83e1b4aba19 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/MLRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/MLRequestConverters.java @@ -28,6 +28,7 @@ import org.apache.lucene.util.BytesRef; import org.elasticsearch.client.RequestConverters.EndpointBuilder; import org.elasticsearch.client.ml.CloseJobRequest; +import org.elasticsearch.client.ml.DeleteCalendarRequest; import org.elasticsearch.client.ml.DeleteDatafeedRequest; import org.elasticsearch.client.ml.DeleteForecastRequest; import org.elasticsearch.client.ml.DeleteJobRequest; @@ -372,4 +373,15 @@ static Request getCalendars(GetCalendarsRequest getCalendarsRequest) throws IOEx request.setEntity(createEntity(getCalendarsRequest, REQUEST_BODY_CONTENT_TYPE)); return request; } + + static Request deleteCalendar(DeleteCalendarRequest deleteCalendarRequest) { + String endpoint = new EndpointBuilder() + .addPathPartAsIs("_xpack") + .addPathPartAsIs("ml") + .addPathPartAsIs("calendars") + .addPathPart(deleteCalendarRequest.getCalendarId()) + .build(); + Request request = new Request(HttpDelete.METHOD_NAME, endpoint); + return request; + } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/MachineLearningClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/MachineLearningClient.java index 5edb5115d857a..06df9b314886d 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/MachineLearningClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/MachineLearningClient.java @@ -22,6 +22,7 @@ import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.client.ml.CloseJobRequest; import org.elasticsearch.client.ml.CloseJobResponse; +import org.elasticsearch.client.ml.DeleteCalendarRequest; import org.elasticsearch.client.ml.DeleteDatafeedRequest; import org.elasticsearch.client.ml.DeleteForecastRequest; import org.elasticsearch.client.ml.DeleteJobRequest; @@ -910,4 +911,44 @@ public void putCalendarAsync(PutCalendarRequest request, RequestOptions options, listener, Collections.emptySet()); } + + /** + * Deletes the given Machine Learning Calendar + *

+ * For additional info see + * + * ML Delete calendar documentation + * + * @param request The request to delete the calendar + * @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 deleteCalendar(DeleteCalendarRequest request, RequestOptions options) throws IOException { + return restHighLevelClient.performRequestAndParseEntity(request, + MLRequestConverters::deleteCalendar, + options, + AcknowledgedResponse::fromXContent, + Collections.emptySet()); + } + + /** + * Deletes the given Machine Learning Job asynchronously and notifies the listener on completion + *

+ * For additional info see + * + * ML Delete calendar documentation + * + * @param request The request to delete the calendar + * @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 deleteCalendarAsync(DeleteCalendarRequest request, RequestOptions options, ActionListener listener) { + restHighLevelClient.performRequestAsyncAndParseEntity(request, + MLRequestConverters::deleteCalendar, + options, + AcknowledgedResponse::fromXContent, + listener, + Collections.emptySet()); + } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/DeleteCalendarRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/DeleteCalendarRequest.java new file mode 100644 index 0000000000000..047561685fbfb --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/DeleteCalendarRequest.java @@ -0,0 +1,65 @@ +/* + * 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 java.util.Objects; + +/** + * Request to delete a Machine Learning Calendar + */ +public class DeleteCalendarRequest extends ActionRequest { + + private final String calendarId; + + /** + * The constructor requires a single calendar id. + * @param calendarId The calendar to delete. Must be {@code non-null} + */ + public DeleteCalendarRequest(String calendarId) { + this.calendarId = Objects.requireNonNull(calendarId, "[calendar_id] must not be null"); + } + + public String getCalendarId() { + return calendarId; + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + @Override + public int hashCode() { + return Objects.hash(calendarId); + } + + @Override + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + + DeleteCalendarRequest other = (DeleteCalendarRequest) obj; + return Objects.equals(calendarId, other.calendarId); + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/MLRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/MLRequestConvertersTests.java index fdd4200ee81b9..819e2f634494d 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/MLRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/MLRequestConvertersTests.java @@ -24,6 +24,7 @@ import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.elasticsearch.client.ml.CloseJobRequest; +import org.elasticsearch.client.ml.DeleteCalendarRequest; import org.elasticsearch.client.ml.DeleteDatafeedRequest; import org.elasticsearch.client.ml.DeleteForecastRequest; import org.elasticsearch.client.ml.DeleteJobRequest; @@ -438,6 +439,13 @@ public void testGetCalendars() throws IOException { } } + public void testDeleteCalendar() { + DeleteCalendarRequest deleteCalendarRequest = new DeleteCalendarRequest(randomAlphaOfLength(10)); + Request request = MLRequestConverters.deleteCalendar(deleteCalendarRequest); + assertEquals(HttpDelete.METHOD_NAME, request.getMethod()); + assertEquals("/_xpack/ml/calendars/" + deleteCalendarRequest.getCalendarId(), request.getEndpoint()); + } + private static Job createValidJob(String jobId) { AnalysisConfig.Builder analysisConfig = AnalysisConfig.builder(Collections.singletonList( Detector.builder().setFunction("count").build())); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/MachineLearningIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/MachineLearningIT.java index e90d541b9c79a..19ca737d6e962 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/MachineLearningIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/MachineLearningIT.java @@ -25,6 +25,7 @@ import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.client.ml.CloseJobRequest; import org.elasticsearch.client.ml.CloseJobResponse; +import org.elasticsearch.client.ml.DeleteCalendarRequest; import org.elasticsearch.client.ml.DeleteDatafeedRequest; import org.elasticsearch.client.ml.DeleteForecastRequest; import org.elasticsearch.client.ml.DeleteJobRequest; @@ -517,6 +518,24 @@ public void testGetCalendars() throws Exception { assertEquals(calendar1, getCalendarsResponse.calendars().get(0)); } + public void testDeleteCalendar() throws IOException { + Calendar calendar = CalendarTests.testInstance(); + MachineLearningClient machineLearningClient = highLevelClient().machineLearning(); + execute(new PutCalendarRequest(calendar), machineLearningClient::putCalendar, + machineLearningClient::putCalendarAsync); + + AcknowledgedResponse response = execute(new DeleteCalendarRequest(calendar.getId()), + machineLearningClient::deleteCalendar, + machineLearningClient::deleteCalendarAsync); + assertTrue(response.isAcknowledged()); + + // calendar is missing + ElasticsearchStatusException exception = expectThrows(ElasticsearchStatusException.class, + () -> execute(new DeleteCalendarRequest(calendar.getId()), machineLearningClient::deleteCalendar, + machineLearningClient::deleteCalendarAsync)); + assertThat(exception.status().getStatus(), equalTo(404)); + } + public static String randomValidJobId() { CodepointSetGenerator generator = new CodepointSetGenerator("abcdefghijklmnopqrstuvwxyz0123456789".toCharArray()); return generator.ofCodePointsLength(random(), 10, 10); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MlClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MlClientDocumentationIT.java index ddaf9d8db6cc8..36d5a08d6d368 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MlClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MlClientDocumentationIT.java @@ -34,6 +34,7 @@ import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.ml.CloseJobRequest; import org.elasticsearch.client.ml.CloseJobResponse; +import org.elasticsearch.client.ml.DeleteCalendarRequest; import org.elasticsearch.client.ml.DeleteDatafeedRequest; import org.elasticsearch.client.ml.DeleteForecastRequest; import org.elasticsearch.client.ml.DeleteJobRequest; @@ -1591,4 +1592,50 @@ public void onFailure(Exception e) { assertTrue(latch.await(30L, TimeUnit.SECONDS)); } } + + public void testDeleteCalendar() throws IOException, InterruptedException { + RestHighLevelClient client = highLevelClient(); + + Calendar calendar = new Calendar("holidays", Collections.singletonList("job_1"), "A calendar for public holidays"); + PutCalendarRequest putCalendarRequest = new PutCalendarRequest(calendar); + client.machineLearning().putCalendar(putCalendarRequest, RequestOptions.DEFAULT); + + //tag::x-pack-ml-delete-calendar-request + DeleteCalendarRequest request = new DeleteCalendarRequest("holidays"); // <1> + //end::x-pack-ml-delete-calendar-request + + //tag::x-pack-ml-delete-calendar-execute + AcknowledgedResponse response = client.machineLearning().deleteCalendar(request, RequestOptions.DEFAULT); + //end::x-pack-ml-delete-calendar-execute + + //tag::x-pack-ml-delete-calendar-response + boolean isAcknowledged = response.isAcknowledged(); // <1> + //end::x-pack-ml-delete-calendar-response + + assertTrue(isAcknowledged); + + // tag::x-pack-ml-delete-calendar-listener + ActionListener listener = new ActionListener() { + @Override + public void onResponse(AcknowledgedResponse response) { + // <1> + } + + @Override + public void onFailure(Exception e) { + // <2> + } + }; + // end::x-pack-ml-delete-calendar-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-delete-calendar-execute-async + client.machineLearning().deleteCalendarAsync(request, RequestOptions.DEFAULT, listener); // <1> + // end::x-pack-ml-delete-calendar-execute-async + + assertTrue(latch.await(30L, TimeUnit.SECONDS)); + } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/DeleteCalendarRequestTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/DeleteCalendarRequestTests.java new file mode 100644 index 0000000000000..850fd800c9a8e --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/DeleteCalendarRequestTests.java @@ -0,0 +1,43 @@ +/* + * 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 static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.not; + + +public class DeleteCalendarRequestTests extends ESTestCase { + + public void testWithNullId() { + NullPointerException ex = expectThrows(NullPointerException.class, () -> new DeleteCalendarRequest(null)); + assertEquals("[calendar_id] must not be null", ex.getMessage()); + } + + public void testEqualsAndHash() { + String id1 = randomAlphaOfLength(8); + String id2 = id1 + "_a"; + assertThat(new DeleteCalendarRequest(id1), equalTo(new DeleteCalendarRequest(id1))); + assertThat(new DeleteCalendarRequest(id1).hashCode(), equalTo(new DeleteCalendarRequest(id1).hashCode())); + assertThat(new DeleteCalendarRequest(id1), not(equalTo(new DeleteCalendarRequest(id2)))); + assertThat(new DeleteCalendarRequest(id1).hashCode(), not(equalTo(new DeleteCalendarRequest(id2).hashCode()))); + } +} diff --git a/docs/java-rest/high-level/ml/delete-calendar.asciidoc b/docs/java-rest/high-level/ml/delete-calendar.asciidoc new file mode 100644 index 0000000000000..8f25576a96f14 --- /dev/null +++ b/docs/java-rest/high-level/ml/delete-calendar.asciidoc @@ -0,0 +1,59 @@ +[[java-rest-high-x-pack-ml-delete-calendar]] +=== Delete Calendar API +Delete a {ml} calendar. +The API accepts a `DeleteCalendarRequest` and responds +with a `AcknowledgedResponse` object. + +[[java-rest-high-x-pack-ml-delete-calendar-request]] +==== Delete Calendar Request + +A `DeleteCalendar` object requires a non-null `calendarId`. + +["source","java",subs="attributes,callouts,macros"] +--------------------------------------------------- +include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-delete-calendar-request] +--------------------------------------------------- +<1> Constructing a new request referencing an existing Calendar + +[[java-rest-high-x-pack-ml-delete-calendar-response]] +==== Delete Calendar Response + +The returned `AcknowledgedResponse` object indicates the acknowledgement of the request: +["source","java",subs="attributes,callouts,macros"] +--------------------------------------------------- +include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-delete-calendar-response] +--------------------------------------------------- +<1> `isAcknowledged` was the deletion request acknowledged or not + +[[java-rest-high-x-pack-ml-delete-calendar-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-delete-calendar-execute] +-------------------------------------------------- + +[[java-rest-high-x-pack-ml-delete-calendar-async]] +==== Delete Calendar Asynchronously + +This request can also be made asynchronously. +["source","java",subs="attributes,callouts,macros"] +--------------------------------------------------- +include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-delete-calendar-execute-async] +--------------------------------------------------- +<1> The `DeleteCalendarRequest` 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 `DeleteCalendarRequest` could be defined as follows: + +["source","java",subs="attributes,callouts,macros"] +--------------------------------------------------- +include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-delete-calendar-listener] +--------------------------------------------------- +<1> The action to be taken when it is completed +<2> What to do when a failure occurs diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc index 2c907dd205376..51d00c403de62 100644 --- a/docs/java-rest/high-level/supported-apis.asciidoc +++ b/docs/java-rest/high-level/supported-apis.asciidoc @@ -233,6 +233,7 @@ The Java High Level REST Client supports the following Machine Learning APIs: * <> * <> * <> +* <> include::ml/put-job.asciidoc[] include::ml/get-job.asciidoc[] @@ -255,6 +256,7 @@ include::ml/get-influencers.asciidoc[] include::ml/get-categories.asciidoc[] include::ml/get-calendars.asciidoc[] include::ml/put-calendar.asciidoc[] +include::ml/delete-calendar.asciidoc[] == Migration APIs