Skip to content

Commit 68c0a29

Browse files
authored
HLRC: Delete ML calendar (#33775)
1 parent 0c77f45 commit 68c0a29

File tree

9 files changed

+296
-0
lines changed

9 files changed

+296
-0
lines changed

client/rest-high-level/src/main/java/org/elasticsearch/client/MLRequestConverters.java

+12
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.apache.lucene.util.BytesRef;
2929
import org.elasticsearch.client.RequestConverters.EndpointBuilder;
3030
import org.elasticsearch.client.ml.CloseJobRequest;
31+
import org.elasticsearch.client.ml.DeleteCalendarRequest;
3132
import org.elasticsearch.client.ml.DeleteDatafeedRequest;
3233
import org.elasticsearch.client.ml.DeleteForecastRequest;
3334
import org.elasticsearch.client.ml.DeleteJobRequest;
@@ -372,4 +373,15 @@ static Request getCalendars(GetCalendarsRequest getCalendarsRequest) throws IOEx
372373
request.setEntity(createEntity(getCalendarsRequest, REQUEST_BODY_CONTENT_TYPE));
373374
return request;
374375
}
376+
377+
static Request deleteCalendar(DeleteCalendarRequest deleteCalendarRequest) {
378+
String endpoint = new EndpointBuilder()
379+
.addPathPartAsIs("_xpack")
380+
.addPathPartAsIs("ml")
381+
.addPathPartAsIs("calendars")
382+
.addPathPart(deleteCalendarRequest.getCalendarId())
383+
.build();
384+
Request request = new Request(HttpDelete.METHOD_NAME, endpoint);
385+
return request;
386+
}
375387
}

client/rest-high-level/src/main/java/org/elasticsearch/client/MachineLearningClient.java

+41
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.elasticsearch.action.support.master.AcknowledgedResponse;
2323
import org.elasticsearch.client.ml.CloseJobRequest;
2424
import org.elasticsearch.client.ml.CloseJobResponse;
25+
import org.elasticsearch.client.ml.DeleteCalendarRequest;
2526
import org.elasticsearch.client.ml.DeleteDatafeedRequest;
2627
import org.elasticsearch.client.ml.DeleteForecastRequest;
2728
import org.elasticsearch.client.ml.DeleteJobRequest;
@@ -910,4 +911,44 @@ public void putCalendarAsync(PutCalendarRequest request, RequestOptions options,
910911
listener,
911912
Collections.emptySet());
912913
}
914+
915+
/**
916+
* Deletes the given Machine Learning Calendar
917+
* <p>
918+
* For additional info see
919+
* <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-calendar.html">
920+
* ML Delete calendar documentation</a>
921+
*
922+
* @param request The request to delete the calendar
923+
* @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
924+
* @return action acknowledgement
925+
* @throws IOException when there is a serialization issue sending the request or receiving the response
926+
*/
927+
public AcknowledgedResponse deleteCalendar(DeleteCalendarRequest request, RequestOptions options) throws IOException {
928+
return restHighLevelClient.performRequestAndParseEntity(request,
929+
MLRequestConverters::deleteCalendar,
930+
options,
931+
AcknowledgedResponse::fromXContent,
932+
Collections.emptySet());
933+
}
934+
935+
/**
936+
* Deletes the given Machine Learning Job asynchronously and notifies the listener on completion
937+
* <p>
938+
* For additional info see
939+
* <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-calendar.html">
940+
* ML Delete calendar documentation</a>
941+
*
942+
* @param request The request to delete the calendar
943+
* @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
944+
* @param listener Listener to be notified upon request completion
945+
*/
946+
public void deleteCalendarAsync(DeleteCalendarRequest request, RequestOptions options, ActionListener<AcknowledgedResponse> listener) {
947+
restHighLevelClient.performRequestAsyncAndParseEntity(request,
948+
MLRequestConverters::deleteCalendar,
949+
options,
950+
AcknowledgedResponse::fromXContent,
951+
listener,
952+
Collections.emptySet());
953+
}
913954
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.client.ml;
21+
22+
import org.elasticsearch.action.ActionRequest;
23+
import org.elasticsearch.action.ActionRequestValidationException;
24+
25+
import java.util.Objects;
26+
27+
/**
28+
* Request to delete a Machine Learning Calendar
29+
*/
30+
public class DeleteCalendarRequest extends ActionRequest {
31+
32+
private final String calendarId;
33+
34+
/**
35+
* The constructor requires a single calendar id.
36+
* @param calendarId The calendar to delete. Must be {@code non-null}
37+
*/
38+
public DeleteCalendarRequest(String calendarId) {
39+
this.calendarId = Objects.requireNonNull(calendarId, "[calendar_id] must not be null");
40+
}
41+
42+
public String getCalendarId() {
43+
return calendarId;
44+
}
45+
46+
@Override
47+
public ActionRequestValidationException validate() {
48+
return null;
49+
}
50+
51+
@Override
52+
public int hashCode() {
53+
return Objects.hash(calendarId);
54+
}
55+
56+
@Override
57+
public boolean equals(Object obj) {
58+
if (obj == null || getClass() != obj.getClass()) {
59+
return false;
60+
}
61+
62+
DeleteCalendarRequest other = (DeleteCalendarRequest) obj;
63+
return Objects.equals(calendarId, other.calendarId);
64+
}
65+
}

client/rest-high-level/src/test/java/org/elasticsearch/client/MLRequestConvertersTests.java

+8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.http.client.methods.HttpPost;
2525
import org.apache.http.client.methods.HttpPut;
2626
import org.elasticsearch.client.ml.CloseJobRequest;
27+
import org.elasticsearch.client.ml.DeleteCalendarRequest;
2728
import org.elasticsearch.client.ml.DeleteDatafeedRequest;
2829
import org.elasticsearch.client.ml.DeleteForecastRequest;
2930
import org.elasticsearch.client.ml.DeleteJobRequest;
@@ -438,6 +439,13 @@ public void testGetCalendars() throws IOException {
438439
}
439440
}
440441

442+
public void testDeleteCalendar() {
443+
DeleteCalendarRequest deleteCalendarRequest = new DeleteCalendarRequest(randomAlphaOfLength(10));
444+
Request request = MLRequestConverters.deleteCalendar(deleteCalendarRequest);
445+
assertEquals(HttpDelete.METHOD_NAME, request.getMethod());
446+
assertEquals("/_xpack/ml/calendars/" + deleteCalendarRequest.getCalendarId(), request.getEndpoint());
447+
}
448+
441449
private static Job createValidJob(String jobId) {
442450
AnalysisConfig.Builder analysisConfig = AnalysisConfig.builder(Collections.singletonList(
443451
Detector.builder().setFunction("count").build()));

client/rest-high-level/src/test/java/org/elasticsearch/client/MachineLearningIT.java

+19
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.elasticsearch.action.support.master.AcknowledgedResponse;
2626
import org.elasticsearch.client.ml.CloseJobRequest;
2727
import org.elasticsearch.client.ml.CloseJobResponse;
28+
import org.elasticsearch.client.ml.DeleteCalendarRequest;
2829
import org.elasticsearch.client.ml.DeleteDatafeedRequest;
2930
import org.elasticsearch.client.ml.DeleteForecastRequest;
3031
import org.elasticsearch.client.ml.DeleteJobRequest;
@@ -517,6 +518,24 @@ public void testGetCalendars() throws Exception {
517518
assertEquals(calendar1, getCalendarsResponse.calendars().get(0));
518519
}
519520

521+
public void testDeleteCalendar() throws IOException {
522+
Calendar calendar = CalendarTests.testInstance();
523+
MachineLearningClient machineLearningClient = highLevelClient().machineLearning();
524+
execute(new PutCalendarRequest(calendar), machineLearningClient::putCalendar,
525+
machineLearningClient::putCalendarAsync);
526+
527+
AcknowledgedResponse response = execute(new DeleteCalendarRequest(calendar.getId()),
528+
machineLearningClient::deleteCalendar,
529+
machineLearningClient::deleteCalendarAsync);
530+
assertTrue(response.isAcknowledged());
531+
532+
// calendar is missing
533+
ElasticsearchStatusException exception = expectThrows(ElasticsearchStatusException.class,
534+
() -> execute(new DeleteCalendarRequest(calendar.getId()), machineLearningClient::deleteCalendar,
535+
machineLearningClient::deleteCalendarAsync));
536+
assertThat(exception.status().getStatus(), equalTo(404));
537+
}
538+
520539
public static String randomValidJobId() {
521540
CodepointSetGenerator generator = new CodepointSetGenerator("abcdefghijklmnopqrstuvwxyz0123456789".toCharArray());
522541
return generator.ofCodePointsLength(random(), 10, 10);

client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MlClientDocumentationIT.java

+47
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.elasticsearch.client.RestHighLevelClient;
3535
import org.elasticsearch.client.ml.CloseJobRequest;
3636
import org.elasticsearch.client.ml.CloseJobResponse;
37+
import org.elasticsearch.client.ml.DeleteCalendarRequest;
3738
import org.elasticsearch.client.ml.DeleteDatafeedRequest;
3839
import org.elasticsearch.client.ml.DeleteForecastRequest;
3940
import org.elasticsearch.client.ml.DeleteJobRequest;
@@ -1591,4 +1592,50 @@ public void onFailure(Exception e) {
15911592
assertTrue(latch.await(30L, TimeUnit.SECONDS));
15921593
}
15931594
}
1595+
1596+
public void testDeleteCalendar() throws IOException, InterruptedException {
1597+
RestHighLevelClient client = highLevelClient();
1598+
1599+
Calendar calendar = new Calendar("holidays", Collections.singletonList("job_1"), "A calendar for public holidays");
1600+
PutCalendarRequest putCalendarRequest = new PutCalendarRequest(calendar);
1601+
client.machineLearning().putCalendar(putCalendarRequest, RequestOptions.DEFAULT);
1602+
1603+
//tag::x-pack-ml-delete-calendar-request
1604+
DeleteCalendarRequest request = new DeleteCalendarRequest("holidays"); // <1>
1605+
//end::x-pack-ml-delete-calendar-request
1606+
1607+
//tag::x-pack-ml-delete-calendar-execute
1608+
AcknowledgedResponse response = client.machineLearning().deleteCalendar(request, RequestOptions.DEFAULT);
1609+
//end::x-pack-ml-delete-calendar-execute
1610+
1611+
//tag::x-pack-ml-delete-calendar-response
1612+
boolean isAcknowledged = response.isAcknowledged(); // <1>
1613+
//end::x-pack-ml-delete-calendar-response
1614+
1615+
assertTrue(isAcknowledged);
1616+
1617+
// tag::x-pack-ml-delete-calendar-listener
1618+
ActionListener<AcknowledgedResponse> listener = new ActionListener<AcknowledgedResponse>() {
1619+
@Override
1620+
public void onResponse(AcknowledgedResponse response) {
1621+
// <1>
1622+
}
1623+
1624+
@Override
1625+
public void onFailure(Exception e) {
1626+
// <2>
1627+
}
1628+
};
1629+
// end::x-pack-ml-delete-calendar-listener
1630+
1631+
// Replace the empty listener by a blocking listener in test
1632+
final CountDownLatch latch = new CountDownLatch(1);
1633+
listener = new LatchedActionListener<>(listener, latch);
1634+
1635+
// tag::x-pack-ml-delete-calendar-execute-async
1636+
client.machineLearning().deleteCalendarAsync(request, RequestOptions.DEFAULT, listener); // <1>
1637+
// end::x-pack-ml-delete-calendar-execute-async
1638+
1639+
assertTrue(latch.await(30L, TimeUnit.SECONDS));
1640+
}
15941641
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.client.ml;
21+
22+
import org.elasticsearch.test.ESTestCase;
23+
24+
import static org.hamcrest.Matchers.equalTo;
25+
import static org.hamcrest.Matchers.not;
26+
27+
28+
public class DeleteCalendarRequestTests extends ESTestCase {
29+
30+
public void testWithNullId() {
31+
NullPointerException ex = expectThrows(NullPointerException.class, () -> new DeleteCalendarRequest(null));
32+
assertEquals("[calendar_id] must not be null", ex.getMessage());
33+
}
34+
35+
public void testEqualsAndHash() {
36+
String id1 = randomAlphaOfLength(8);
37+
String id2 = id1 + "_a";
38+
assertThat(new DeleteCalendarRequest(id1), equalTo(new DeleteCalendarRequest(id1)));
39+
assertThat(new DeleteCalendarRequest(id1).hashCode(), equalTo(new DeleteCalendarRequest(id1).hashCode()));
40+
assertThat(new DeleteCalendarRequest(id1), not(equalTo(new DeleteCalendarRequest(id2))));
41+
assertThat(new DeleteCalendarRequest(id1).hashCode(), not(equalTo(new DeleteCalendarRequest(id2).hashCode())));
42+
}
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
[[java-rest-high-x-pack-ml-delete-calendar]]
2+
=== Delete Calendar API
3+
Delete a {ml} calendar.
4+
The API accepts a `DeleteCalendarRequest` and responds
5+
with a `AcknowledgedResponse` object.
6+
7+
[[java-rest-high-x-pack-ml-delete-calendar-request]]
8+
==== Delete Calendar Request
9+
10+
A `DeleteCalendar` object requires a non-null `calendarId`.
11+
12+
["source","java",subs="attributes,callouts,macros"]
13+
---------------------------------------------------
14+
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-delete-calendar-request]
15+
---------------------------------------------------
16+
<1> Constructing a new request referencing an existing Calendar
17+
18+
[[java-rest-high-x-pack-ml-delete-calendar-response]]
19+
==== Delete Calendar Response
20+
21+
The returned `AcknowledgedResponse` object indicates the acknowledgement of the request:
22+
["source","java",subs="attributes,callouts,macros"]
23+
---------------------------------------------------
24+
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-delete-calendar-response]
25+
---------------------------------------------------
26+
<1> `isAcknowledged` was the deletion request acknowledged or not
27+
28+
[[java-rest-high-x-pack-ml-delete-calendar-execution]]
29+
==== Execution
30+
The request can be executed through the `MachineLearningClient` contained
31+
in the `RestHighLevelClient` object, accessed via the `machineLearningClient()` method.
32+
33+
["source","java",subs="attributes,callouts,macros"]
34+
--------------------------------------------------
35+
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-delete-calendar-execute]
36+
--------------------------------------------------
37+
38+
[[java-rest-high-x-pack-ml-delete-calendar-async]]
39+
==== Delete Calendar Asynchronously
40+
41+
This request can also be made asynchronously.
42+
["source","java",subs="attributes,callouts,macros"]
43+
---------------------------------------------------
44+
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-delete-calendar-execute-async]
45+
---------------------------------------------------
46+
<1> The `DeleteCalendarRequest` to execute and the `ActionListener` to alert on completion or error.
47+
48+
The deletion request returns immediately. Once the request is completed, the `ActionListener` is
49+
called back using the `onResponse` or `onFailure`. The latter indicates some failure occurred when
50+
making the request.
51+
52+
A typical listener for a `DeleteCalendarRequest` could be defined as follows:
53+
54+
["source","java",subs="attributes,callouts,macros"]
55+
---------------------------------------------------
56+
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-delete-calendar-listener]
57+
---------------------------------------------------
58+
<1> The action to be taken when it is completed
59+
<2> What to do when a failure occurs

docs/java-rest/high-level/supported-apis.asciidoc

+2
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ The Java High Level REST Client supports the following Machine Learning APIs:
233233
* <<java-rest-high-x-pack-ml-get-categories>>
234234
* <<java-rest-high-x-pack-ml-get-calendars>>
235235
* <<java-rest-high-x-pack-ml-put-calendar>>
236+
* <<java-rest-high-x-pack-ml-delete-calendar>>
236237

237238
include::ml/put-job.asciidoc[]
238239
include::ml/get-job.asciidoc[]
@@ -255,6 +256,7 @@ include::ml/get-influencers.asciidoc[]
255256
include::ml/get-categories.asciidoc[]
256257
include::ml/get-calendars.asciidoc[]
257258
include::ml/put-calendar.asciidoc[]
259+
include::ml/delete-calendar.asciidoc[]
258260

259261
== Migration APIs
260262

0 commit comments

Comments
 (0)