Skip to content

Commit f76f95b

Browse files
authored
[ML] Filter undefined job groups from update calendar actions (#30757)
The UI creates job groups in calendars ad hoc to ease calendar creation these must be filtered from the jobs list before applying updates.
1 parent bdb79d0 commit f76f95b

File tree

5 files changed

+115
-30
lines changed

5 files changed

+115
-30
lines changed

x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportUpdateCalendarJobAction.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,35 +28,28 @@
2828

2929
public class TransportUpdateCalendarJobAction extends HandledTransportAction<UpdateCalendarJobAction.Request, PutCalendarAction.Response> {
3030

31-
private final ClusterService clusterService;
3231
private final JobProvider jobProvider;
3332
private final JobManager jobManager;
3433

3534
@Inject
3635
public TransportUpdateCalendarJobAction(Settings settings, ThreadPool threadPool,
3736
TransportService transportService, ActionFilters actionFilters,
3837
IndexNameExpressionResolver indexNameExpressionResolver,
39-
ClusterService clusterService, JobProvider jobProvider, JobManager jobManager) {
38+
JobProvider jobProvider, JobManager jobManager) {
4039
super(settings, UpdateCalendarJobAction.NAME, threadPool, transportService, actionFilters,
4140
indexNameExpressionResolver, UpdateCalendarJobAction.Request::new);
42-
this.clusterService = clusterService;
4341
this.jobProvider = jobProvider;
4442
this.jobManager = jobManager;
4543
}
4644

4745
@Override
4846
protected void doExecute(UpdateCalendarJobAction.Request request, ActionListener<PutCalendarAction.Response> listener) {
49-
ClusterState clusterState = clusterService.state();
50-
final MlMetadata mlMetadata = MlMetadata.getMlMetadata(clusterState);
51-
5247
Set<String> jobIdsToAdd = Strings.tokenizeByCommaToSet(request.getJobIdsToAddExpression());
5348
Set<String> jobIdsToRemove = Strings.tokenizeByCommaToSet(request.getJobIdsToRemoveExpression());
5449

55-
jobProvider.updateCalendar(request.getCalendarId(), jobIdsToAdd, jobIdsToRemove, mlMetadata,
50+
jobProvider.updateCalendar(request.getCalendarId(), jobIdsToAdd, jobIdsToRemove,
5651
c -> {
57-
List<String> existingJobsOrGroups =
58-
c.getJobIds().stream().filter(mlMetadata::isGroupOrJob).collect(Collectors.toList());
59-
jobManager.updateProcessOnCalendarChanged(existingJobsOrGroups);
52+
jobManager.updateProcessOnCalendarChanged(c.getJobIds());
6053
listener.onResponse(new PutCalendarAction.Response(c));
6154
}, listener::onFailure);
6255
}

x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/JobManager.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
import java.util.function.Consumer;
6868
import java.util.regex.Matcher;
6969
import java.util.regex.Pattern;
70+
import java.util.stream.Collectors;
7071

7172
/**
7273
* Allows interactions with jobs. The managed interactions include:
@@ -420,8 +421,13 @@ public void updateProcessOnFilterChanged(MlFilter filter) {
420421

421422
public void updateProcessOnCalendarChanged(List<String> calendarJobIds) {
422423
ClusterState clusterState = clusterService.state();
424+
MlMetadata mlMetadata = MlMetadata.getMlMetadata(clusterState);
425+
426+
List<String> existingJobsOrGroups =
427+
calendarJobIds.stream().filter(mlMetadata::isGroupOrJob).collect(Collectors.toList());
428+
423429
Set<String> expandedJobIds = new HashSet<>();
424-
calendarJobIds.forEach(jobId -> expandedJobIds.addAll(expandJobIds(jobId, true, clusterState)));
430+
existingJobsOrGroups.forEach(jobId -> expandedJobIds.addAll(expandJobIds(jobId, true, clusterState)));
425431
for (String jobId : expandedJobIds) {
426432
if (isJobOpen(clusterState, jobId)) {
427433
updateJobProcessNotifier.submitJobUpdate(UpdateParams.scheduledEventsUpdate(jobId), ActionListener.wrap(

x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/persistence/JobProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1114,7 +1114,7 @@ public void getForecastRequestStats(String jobId, String forecastId, Consumer<Fo
11141114
result -> handler.accept(result.result), errorHandler, () -> null);
11151115
}
11161116

1117-
public void updateCalendar(String calendarId, Set<String> jobIdsToAdd, Set<String> jobIdsToRemove, MlMetadata mlMetadata,
1117+
public void updateCalendar(String calendarId, Set<String> jobIdsToAdd, Set<String> jobIdsToRemove,
11181118
Consumer<Calendar> handler, Consumer<Exception> errorHandler) {
11191119

11201120
ActionListener<Calendar> getCalendarListener = ActionListener.wrap(

x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/integration/JobProviderIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ private void updateCalendar(String calendarId, Set<String> idsToAdd, Set<String>
244244
throws Exception {
245245
CountDownLatch latch = new CountDownLatch(1);
246246
AtomicReference<Exception> exceptionHolder = new AtomicReference<>();
247-
jobProvider.updateCalendar(calendarId, idsToAdd, idsToRemove, mlMetadata,
247+
jobProvider.updateCalendar(calendarId, idsToAdd, idsToRemove,
248248
r -> latch.countDown(),
249249
e -> {
250250
exceptionHolder.set(e);

x-pack/plugin/src/test/resources/rest-api-spec/test/ml/calendar_crud.yml

Lines changed: 103 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -86,23 +86,6 @@
8686
xpack.ml.get_calendars:
8787
calendar_id: "dogs_of_the_year"
8888

89-
- do:
90-
xpack.ml.put_calendar:
91-
calendar_id: "new_cal_with_unknown_job_group"
92-
body: >
93-
{
94-
"job_ids": ["cal-job", "unknown-job-group"]
95-
}
96-
97-
- do:
98-
xpack.ml.get_calendars:
99-
calendar_id: "new_cal_with_unknown_job_group"
100-
- match: { count: 1 }
101-
- match:
102-
calendars.0:
103-
calendar_id: "new_cal_with_unknown_job_group"
104-
job_ids: ["cal-job", "unknown-job-group"]
105-
10689
---
10790
"Test get calendar given missing":
10891
- do:
@@ -714,3 +697,106 @@
714697
- match: { calendar_id: "expression" }
715698
- length: { job_ids: 1 }
716699
- match: { job_ids.0: "bar-a" }
700+
701+
---
702+
"Test calendar actions with new job group":
703+
- do:
704+
xpack.ml.put_job:
705+
job_id: calendar-job
706+
body: >
707+
{
708+
"analysis_config" : {
709+
"detectors" :[{"function":"metric","field_name":"responsetime","by_field_name":"airline"}]
710+
},
711+
"data_description" : {
712+
}
713+
}
714+
715+
- do:
716+
xpack.ml.put_calendar:
717+
calendar_id: "cal_with_new_job_group"
718+
body: >
719+
{
720+
"job_ids": ["calendar-job", "new-job-group"]
721+
}
722+
723+
- do:
724+
xpack.ml.get_calendars:
725+
calendar_id: "cal_with_new_job_group"
726+
- match: { count: 1 }
727+
- match:
728+
calendars.0:
729+
calendar_id: "cal_with_new_job_group"
730+
job_ids: ["calendar-job", "new-job-group"]
731+
732+
- do:
733+
xpack.ml.post_calendar_events:
734+
calendar_id: "cal_with_new_job_group"
735+
body: >
736+
{
737+
"events" : [{ "description": "beach", "start_time": "2018-05-01T00:00:00Z", "end_time": "2018-05-06T00:00:00Z" }]
738+
}
739+
740+
- do:
741+
xpack.ml.get_calendar_events:
742+
calendar_id: cal_with_new_job_group
743+
- length: { events: 1 }
744+
- match: { events.0.description: beach }
745+
746+
- do:
747+
xpack.ml.delete_calendar:
748+
calendar_id: "cal_with_new_job_group"
749+
750+
- do:
751+
xpack.ml.put_calendar:
752+
calendar_id: "started_empty_calendar"
753+
754+
- do:
755+
xpack.ml.put_calendar_job:
756+
calendar_id: "started_empty_calendar"
757+
job_id: "new-group"
758+
- match: { calendar_id: "started_empty_calendar" }
759+
- length: { job_ids: 1 }
760+
761+
- do:
762+
xpack.ml.get_calendars:
763+
calendar_id: "started_empty_calendar"
764+
- match: { count: 1 }
765+
- match:
766+
calendars.0:
767+
calendar_id: "started_empty_calendar"
768+
job_ids: ["new-group"]
769+
770+
- do:
771+
xpack.ml.post_calendar_events:
772+
calendar_id: "started_empty_calendar"
773+
body: >
774+
{
775+
"events" : [{ "description": "beach", "start_time": "2018-05-01T00:00:00Z", "end_time": "2018-05-06T00:00:00Z" }]
776+
}
777+
778+
- do:
779+
xpack.ml.get_calendar_events:
780+
calendar_id: "started_empty_calendar"
781+
- length: { events: 1 }
782+
- match: { events.0.description: beach }
783+
- set: { events.0.event_id: beach_event_id }
784+
785+
- do:
786+
xpack.ml.delete_calendar_event:
787+
calendar_id: "started_empty_calendar"
788+
event_id: $beach_event_id
789+
790+
- do:
791+
xpack.ml.get_calendar_events:
792+
calendar_id: "started_empty_calendar"
793+
- length: { events: 0 }
794+
795+
- do:
796+
xpack.ml.delete_calendar:
797+
calendar_id: "started_empty_calendar"
798+
799+
- do:
800+
catch: missing
801+
xpack.ml.get_calendars:
802+
calendar_id: "started_empty_calendar"

0 commit comments

Comments
 (0)