Skip to content

Commit 90a8e4b

Browse files
authored
HLRC: ML Delete event from Calendar (#35760)
* HLRC: Delete event from calendar * adjusting tests * adjusting code to make it more readable
1 parent d95d885 commit 90a8e4b

File tree

10 files changed

+325
-2
lines changed

10 files changed

+325
-2
lines changed

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

Lines changed: 13 additions & 0 deletions
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.DeleteCalendarEventRequest;
3132
import org.elasticsearch.client.ml.DeleteCalendarJobRequest;
3233
import org.elasticsearch.client.ml.DeleteCalendarRequest;
3334
import org.elasticsearch.client.ml.DeleteDatafeedRequest;
@@ -584,6 +585,18 @@ static Request postCalendarEvents(PostCalendarEventRequest postCalendarEventRequ
584585
return request;
585586
}
586587

588+
static Request deleteCalendarEvent(DeleteCalendarEventRequest deleteCalendarEventRequest) {
589+
String endpoint = new EndpointBuilder()
590+
.addPathPartAsIs("_xpack")
591+
.addPathPartAsIs("ml")
592+
.addPathPartAsIs("calendars")
593+
.addPathPart(deleteCalendarEventRequest.getCalendarId())
594+
.addPathPartAsIs("events")
595+
.addPathPart(deleteCalendarEventRequest.getEventId())
596+
.build();
597+
return new Request(HttpDelete.METHOD_NAME, endpoint);
598+
}
599+
587600
static Request putFilter(PutFilterRequest putFilterRequest) throws IOException {
588601
String endpoint = new EndpointBuilder()
589602
.addPathPartAsIs("_xpack")

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

Lines changed: 43 additions & 0 deletions
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.DeleteCalendarEventRequest;
2526
import org.elasticsearch.client.ml.DeleteCalendarJobRequest;
2627
import org.elasticsearch.client.ml.DeleteCalendarRequest;
2728
import org.elasticsearch.client.ml.DeleteDatafeedRequest;
@@ -1513,6 +1514,48 @@ public void postCalendarEventAsync(PostCalendarEventRequest request, RequestOpti
15131514
Collections.emptySet());
15141515
}
15151516

1517+
/**
1518+
* Removes a Scheduled Event from a calendar
1519+
* <p>
1520+
* For additional info
1521+
* see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-calendar-event.html">
1522+
* ML Delete calendar event documentation</a>
1523+
*
1524+
* @param request The request
1525+
* @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
1526+
* @return The {@link PutCalendarResponse} containing the updated calendar
1527+
* @throws IOException when there is a serialization issue sending the request or receiving the response
1528+
*/
1529+
public AcknowledgedResponse deleteCalendarEvent(DeleteCalendarEventRequest request, RequestOptions options) throws IOException {
1530+
return restHighLevelClient.performRequestAndParseEntity(request,
1531+
MLRequestConverters::deleteCalendarEvent,
1532+
options,
1533+
AcknowledgedResponse::fromXContent,
1534+
Collections.emptySet());
1535+
}
1536+
1537+
/**
1538+
* Removes a Scheduled Event from a calendar, notifies listener when completed
1539+
* <p>
1540+
* For additional info
1541+
* see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-calendar-event.html">
1542+
* ML Delete calendar event documentation</a>
1543+
*
1544+
* @param request The request
1545+
* @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
1546+
* @param listener Listener to be notified upon request completion
1547+
*/
1548+
public void deleteCalendarEventAsync(DeleteCalendarEventRequest request,
1549+
RequestOptions options,
1550+
ActionListener<AcknowledgedResponse> listener) {
1551+
restHighLevelClient.performRequestAsyncAndParseEntity(request,
1552+
MLRequestConverters::deleteCalendarEvent,
1553+
options,
1554+
AcknowledgedResponse::fromXContent,
1555+
listener,
1556+
Collections.emptySet());
1557+
}
1558+
15161559
/**
15171560
* Creates a new Machine Learning Filter
15181561
* <p>
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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+
package org.elasticsearch.client.ml;
20+
21+
import org.elasticsearch.action.ActionRequest;
22+
import org.elasticsearch.action.ActionRequestValidationException;
23+
24+
import java.util.Objects;
25+
26+
/**
27+
* Request class for removing an event from an existing calendar
28+
*/
29+
public class DeleteCalendarEventRequest extends ActionRequest {
30+
31+
private final String eventId;
32+
private final String calendarId;
33+
34+
/**
35+
* Create a new request referencing an existing Calendar and which event to remove
36+
* from it.
37+
*
38+
* @param calendarId The non-null ID of the calendar
39+
* @param eventId Scheduled Event to remove from the calendar, Cannot be null.
40+
*/
41+
public DeleteCalendarEventRequest(String calendarId, String eventId) {
42+
this.calendarId = Objects.requireNonNull(calendarId, "[calendar_id] must not be null.");
43+
this.eventId = Objects.requireNonNull(eventId, "[event_id] must not be null.");
44+
}
45+
46+
public String getEventId() {
47+
return eventId;
48+
}
49+
50+
public String getCalendarId() {
51+
return calendarId;
52+
}
53+
54+
@Override
55+
public ActionRequestValidationException validate() {
56+
return null;
57+
}
58+
59+
@Override
60+
public int hashCode() {
61+
return Objects.hash(eventId, calendarId);
62+
}
63+
64+
@Override
65+
public boolean equals(Object other) {
66+
if (this == other) {
67+
return true;
68+
}
69+
70+
if (other == null || getClass() != other.getClass()) {
71+
return false;
72+
}
73+
74+
DeleteCalendarEventRequest that = (DeleteCalendarEventRequest) other;
75+
return Objects.equals(eventId, that.eventId) &&
76+
Objects.equals(calendarId, that.calendarId);
77+
}
78+
}

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

Lines changed: 10 additions & 0 deletions
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.DeleteCalendarEventRequest;
2728
import org.elasticsearch.client.ml.DeleteCalendarJobRequest;
2829
import org.elasticsearch.client.ml.DeleteCalendarRequest;
2930
import org.elasticsearch.client.ml.DeleteDatafeedRequest;
@@ -644,6 +645,15 @@ public void testPostCalendarEvent() throws Exception {
644645
assertEquals(Strings.toString(builder), requestEntityToString(request));
645646
}
646647

648+
public void testDeleteCalendarEvent() {
649+
String calendarId = randomAlphaOfLength(10);
650+
String eventId = randomAlphaOfLength(5);
651+
DeleteCalendarEventRequest deleteCalendarEventRequest = new DeleteCalendarEventRequest(calendarId, eventId);
652+
Request request = MLRequestConverters.deleteCalendarEvent(deleteCalendarEventRequest);
653+
assertEquals(HttpDelete.METHOD_NAME, request.getMethod());
654+
assertEquals("/_xpack/ml/calendars/" + calendarId + "/events/" + eventId, request.getEndpoint());
655+
}
656+
647657
public void testPutFilter() throws IOException {
648658
MlFilter filter = MlFilterTests.createRandomBuilder("foo").build();
649659
PutFilterRequest putFilterRequest = new PutFilterRequest(filter);

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.elasticsearch.action.support.master.AcknowledgedResponse;
3030
import org.elasticsearch.client.ml.CloseJobRequest;
3131
import org.elasticsearch.client.ml.CloseJobResponse;
32+
import org.elasticsearch.client.ml.DeleteCalendarEventRequest;
3233
import org.elasticsearch.client.ml.DeleteCalendarJobRequest;
3334
import org.elasticsearch.client.ml.DeleteCalendarRequest;
3435
import org.elasticsearch.client.ml.DeleteDatafeedRequest;
@@ -119,7 +120,9 @@
119120
import java.util.stream.Collectors;
120121

121122
import static org.hamcrest.CoreMatchers.equalTo;
123+
import static org.hamcrest.CoreMatchers.hasItem;
122124
import static org.hamcrest.CoreMatchers.hasItems;
125+
import static org.hamcrest.CoreMatchers.not;
123126
import static org.hamcrest.Matchers.contains;
124127
import static org.hamcrest.Matchers.containsInAnyOrder;
125128
import static org.hamcrest.Matchers.hasSize;
@@ -986,6 +989,42 @@ public void testPostCalendarEvent() throws Exception {
986989
assertThat(postCalendarEventResponse.getScheduledEvents(), containsInAnyOrder(events.toArray()));
987990
}
988991

992+
public void testDeleteCalendarEvent() throws IOException {
993+
Calendar calendar = CalendarTests.testInstance();
994+
MachineLearningClient machineLearningClient = highLevelClient().machineLearning();
995+
machineLearningClient.putCalendar(new PutCalendarRequest(calendar), RequestOptions.DEFAULT);
996+
997+
List<ScheduledEvent> events = new ArrayList<>(3);
998+
for (int i = 0; i < 3; i++) {
999+
events.add(ScheduledEventTests.testInstance(calendar.getId(), null));
1000+
}
1001+
1002+
machineLearningClient.postCalendarEvent(new PostCalendarEventRequest(calendar.getId(), events), RequestOptions.DEFAULT);
1003+
GetCalendarEventsResponse getCalendarEventsResponse =
1004+
machineLearningClient.getCalendarEvents(new GetCalendarEventsRequest(calendar.getId()), RequestOptions.DEFAULT);
1005+
1006+
assertThat(getCalendarEventsResponse.events().size(), equalTo(3));
1007+
String deletedEvent = getCalendarEventsResponse.events().get(0).getEventId();
1008+
1009+
DeleteCalendarEventRequest deleteCalendarEventRequest = new DeleteCalendarEventRequest(calendar.getId(), deletedEvent);
1010+
1011+
AcknowledgedResponse response = execute(deleteCalendarEventRequest,
1012+
machineLearningClient::deleteCalendarEvent,
1013+
machineLearningClient::deleteCalendarEventAsync);
1014+
1015+
assertThat(response.isAcknowledged(), is(true));
1016+
1017+
getCalendarEventsResponse =
1018+
machineLearningClient.getCalendarEvents(new GetCalendarEventsRequest(calendar.getId()), RequestOptions.DEFAULT);
1019+
List<String> remainingIds = getCalendarEventsResponse.events()
1020+
.stream()
1021+
.map(ScheduledEvent::getEventId)
1022+
.collect(Collectors.toList());
1023+
1024+
assertThat(remainingIds.size(), equalTo(2));
1025+
assertThat(remainingIds, not(hasItem(deletedEvent)));
1026+
}
1027+
9891028
public void testPutFilter() throws Exception {
9901029
String filterId = "filter-job-test";
9911030
MlFilter mlFilter = MlFilter.builder(filterId)

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

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.elasticsearch.client.RestHighLevelClient;
3636
import org.elasticsearch.client.ml.CloseJobRequest;
3737
import org.elasticsearch.client.ml.CloseJobResponse;
38+
import org.elasticsearch.client.ml.DeleteCalendarEventRequest;
3839
import org.elasticsearch.client.ml.DeleteCalendarJobRequest;
3940
import org.elasticsearch.client.ml.DeleteCalendarRequest;
4041
import org.elasticsearch.client.ml.DeleteDatafeedRequest;
@@ -2590,7 +2591,71 @@ public void onFailure(Exception e) {
25902591
assertTrue(latch.await(30L, TimeUnit.SECONDS));
25912592
}
25922593
}
2593-
2594+
2595+
public void testDeleteCalendarEvent() throws IOException, InterruptedException {
2596+
RestHighLevelClient client = highLevelClient();
2597+
2598+
Calendar calendar = new Calendar("holidays",
2599+
Arrays.asList("job_1", "job_group_1", "job_2"),
2600+
"A calendar for public holidays");
2601+
PutCalendarRequest putRequest = new PutCalendarRequest(calendar);
2602+
client.machineLearning().putCalendar(putRequest, RequestOptions.DEFAULT);
2603+
List<ScheduledEvent> events = Arrays.asList(ScheduledEventTests.testInstance(calendar.getId(), null),
2604+
ScheduledEventTests.testInstance(calendar.getId(), null));
2605+
client.machineLearning().postCalendarEvent(new PostCalendarEventRequest("holidays", events), RequestOptions.DEFAULT);
2606+
GetCalendarEventsResponse getCalendarEventsResponse =
2607+
client.machineLearning().getCalendarEvents(new GetCalendarEventsRequest("holidays"), RequestOptions.DEFAULT);
2608+
{
2609+
2610+
// tag::delete-calendar-event-request
2611+
DeleteCalendarEventRequest request = new DeleteCalendarEventRequest("holidays", // <1>
2612+
"EventId"); // <2>
2613+
// end::delete-calendar-event-request
2614+
2615+
request = new DeleteCalendarEventRequest("holidays", getCalendarEventsResponse.events().get(0).getEventId());
2616+
2617+
// tag::delete-calendar-event-execute
2618+
AcknowledgedResponse response = client.machineLearning().deleteCalendarEvent(request, RequestOptions.DEFAULT);
2619+
// end::delete-calendar-event-execute
2620+
2621+
// tag::delete-calendar-event-response
2622+
boolean acknowledged = response.isAcknowledged(); // <1>
2623+
// end::delete-calendar-event-response
2624+
2625+
assertThat(acknowledged, is(true));
2626+
}
2627+
{
2628+
DeleteCalendarEventRequest request = new DeleteCalendarEventRequest("holidays",
2629+
getCalendarEventsResponse.events().get(1).getEventId());
2630+
2631+
// tag::delete-calendar-event-execute-listener
2632+
ActionListener<AcknowledgedResponse> listener =
2633+
new ActionListener<AcknowledgedResponse>() {
2634+
@Override
2635+
public void onResponse(AcknowledgedResponse deleteCalendarEventResponse) {
2636+
// <1>
2637+
}
2638+
2639+
@Override
2640+
public void onFailure(Exception e) {
2641+
// <2>
2642+
}
2643+
};
2644+
// end::delete-calendar-event-execute-listener
2645+
2646+
// Replace the empty listener by a blocking listener in test
2647+
final CountDownLatch latch = new CountDownLatch(1);
2648+
listener = new LatchedActionListener<>(listener, latch);
2649+
2650+
// tag::delete-calendar-event-execute-async
2651+
client.machineLearning().deleteCalendarEventAsync(request, RequestOptions.DEFAULT, listener); // <1>
2652+
// end::delete-calendar-event-execute-async
2653+
2654+
assertTrue(latch.await(30L, TimeUnit.SECONDS));
2655+
}
2656+
}
2657+
2658+
25942659
public void testCreateFilter() throws Exception {
25952660
RestHighLevelClient client = highLevelClient();
25962661
{
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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+
public class DeleteCalendarEventRequestTests extends ESTestCase {
25+
26+
public void testWithNullId() {
27+
NullPointerException ex = expectThrows(NullPointerException.class,
28+
() -> new DeleteCalendarEventRequest(null, "event1"));
29+
assertEquals("[calendar_id] must not be null.", ex.getMessage());
30+
}
31+
32+
public void testWithNullEvent() {
33+
NullPointerException ex = expectThrows(NullPointerException.class,
34+
() ->new DeleteCalendarEventRequest("calendarId", null));
35+
assertEquals("[event_id] must not be null.", ex.getMessage());
36+
}
37+
}

0 commit comments

Comments
 (0)