From bee58f8b818ee9681d95b6236f818edff0a54245 Mon Sep 17 00:00:00 2001 From: Dimitris Athanasiou Date: Tue, 20 Dec 2016 10:09:45 +0000 Subject: [PATCH] Add get API for schedulers (elastic/elasticsearch#582) Original commit: elastic/x-pack-elasticsearch@59c555d60abbc302cbe421e125143771d7652125 --- .../xpack/prelert/PrelertPlugin.java | 8 + .../prelert/action/GetJobsStatsAction.java | 25 +- .../prelert/action/GetSchedulersAction.java | 237 ++++++++++++++ .../action/GetSchedulersStatsAction.java | 300 ++++++++++++++++++ .../xpack/prelert/job/messages/Messages.java | 1 - .../prelert/job/metadata/PrelertMetadata.java | 4 +- .../schedulers/RestGetSchedulersAction.java | 40 +++ .../RestGetSchedulersStatsAction.java | 41 +++ .../prelert/scheduler/ScheduledJobRunner.java | 2 +- .../xpack/prelert/scheduler/Scheduler.java | 3 + .../prelert/scheduler/SchedulerConfig.java | 11 - .../xpack/prelert/utils/ExceptionsHelper.java | 4 + .../job/messages/prelert_messages.properties | 1 - ...ts.java => GetJobsActionRequestTests.java} | 2 +- ...s.java => GetJobsActionResponseTests.java} | 2 +- .../GetJobsStatsActionResponseTests.java | 7 +- .../GetSchedulersActionRequestTests.java | 24 ++ .../GetSchedulersActionResponseTests.java | 62 ++++ .../GetSchedulersStatsActionRequestTests.java | 24 ++ ...GetSchedulersStatsActionResponseTests.java | 43 +++ .../scheduler/SchedulerConfigTests.java | 21 +- .../api/xpack.prelert.get_schedulers.json | 19 ++ .../xpack.prelert.get_schedulers_stats.json | 19 ++ .../rest-api-spec/test/get_schedulers.yaml | 87 +++++ .../test/get_schedulers_stats.yaml | 87 +++++ .../rest-api-spec/test/jobs_get_stats.yaml | 2 - .../test/start_stop_scheduler.yaml | 12 +- 27 files changed, 1016 insertions(+), 72 deletions(-) create mode 100644 elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/action/GetSchedulersAction.java create mode 100644 elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/action/GetSchedulersStatsAction.java create mode 100644 elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/rest/schedulers/RestGetSchedulersAction.java create mode 100644 elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/rest/schedulers/RestGetSchedulersStatsAction.java rename elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/{GetJobActionRequestTests.java => GetJobsActionRequestTests.java} (88%) rename elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/{GetJobActionResponseTests.java => GetJobsActionResponseTests.java} (97%) create mode 100644 elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersActionRequestTests.java create mode 100644 elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersActionResponseTests.java create mode 100644 elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersStatsActionRequestTests.java create mode 100644 elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersStatsActionResponseTests.java create mode 100644 elasticsearch/src/test/resources/rest-api-spec/api/xpack.prelert.get_schedulers.json create mode 100644 elasticsearch/src/test/resources/rest-api-spec/api/xpack.prelert.get_schedulers_stats.json create mode 100644 elasticsearch/src/test/resources/rest-api-spec/test/get_schedulers.yaml create mode 100644 elasticsearch/src/test/resources/rest-api-spec/test/get_schedulers_stats.yaml diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/PrelertPlugin.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/PrelertPlugin.java index 67f355e6781..169327ccd92 100644 --- a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/PrelertPlugin.java +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/PrelertPlugin.java @@ -41,6 +41,8 @@ import org.elasticsearch.xpack.prelert.action.GetJobsStatsAction; import org.elasticsearch.xpack.prelert.action.GetListAction; import org.elasticsearch.xpack.prelert.action.GetModelSnapshotsAction; import org.elasticsearch.xpack.prelert.action.GetRecordsAction; +import org.elasticsearch.xpack.prelert.action.GetSchedulersAction; +import org.elasticsearch.xpack.prelert.action.GetSchedulersStatsAction; import org.elasticsearch.xpack.prelert.action.JobDataAction; import org.elasticsearch.xpack.prelert.action.OpenJobAction; import org.elasticsearch.xpack.prelert.action.PutJobAction; @@ -99,6 +101,8 @@ import org.elasticsearch.xpack.prelert.rest.results.RestGetCategoriesAction; import org.elasticsearch.xpack.prelert.rest.results.RestGetInfluencersAction; import org.elasticsearch.xpack.prelert.rest.results.RestGetRecordsAction; import org.elasticsearch.xpack.prelert.rest.schedulers.RestDeleteSchedulerAction; +import org.elasticsearch.xpack.prelert.rest.schedulers.RestGetSchedulersAction; +import org.elasticsearch.xpack.prelert.rest.schedulers.RestGetSchedulersStatsAction; import org.elasticsearch.xpack.prelert.rest.schedulers.RestPutSchedulerAction; import org.elasticsearch.xpack.prelert.rest.schedulers.RestStartSchedulerAction; import org.elasticsearch.xpack.prelert.rest.schedulers.RestStopSchedulerAction; @@ -246,6 +250,8 @@ public class PrelertPlugin extends Plugin implements ActionPlugin { RestGetModelSnapshotsAction.class, RestRevertModelSnapshotAction.class, RestPutModelSnapshotDescriptionAction.class, + RestGetSchedulersAction.class, + RestGetSchedulersStatsAction.class, RestPutSchedulerAction.class, RestDeleteSchedulerAction.class, RestStartSchedulerAction.class, @@ -280,6 +286,8 @@ public class PrelertPlugin extends Plugin implements ActionPlugin { new ActionHandler<>(GetModelSnapshotsAction.INSTANCE, GetModelSnapshotsAction.TransportAction.class), new ActionHandler<>(RevertModelSnapshotAction.INSTANCE, RevertModelSnapshotAction.TransportAction.class), new ActionHandler<>(PutModelSnapshotDescriptionAction.INSTANCE, PutModelSnapshotDescriptionAction.TransportAction.class), + new ActionHandler<>(GetSchedulersAction.INSTANCE, GetSchedulersAction.TransportAction.class), + new ActionHandler<>(GetSchedulersStatsAction.INSTANCE, GetSchedulersStatsAction.TransportAction.class), new ActionHandler<>(PutSchedulerAction.INSTANCE, PutSchedulerAction.TransportAction.class), new ActionHandler<>(DeleteSchedulerAction.INSTANCE, DeleteSchedulerAction.TransportAction.class), new ActionHandler<>(StartSchedulerAction.INSTANCE, StartSchedulerAction.TransportAction.class), diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/action/GetJobsStatsAction.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/action/GetJobsStatsAction.java index 37524497b21..fb7cdb8c556 100644 --- a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/action/GetJobsStatsAction.java +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/action/GetJobsStatsAction.java @@ -38,7 +38,6 @@ import org.elasticsearch.xpack.prelert.job.manager.JobManager; import org.elasticsearch.xpack.prelert.job.metadata.PrelertMetadata; import org.elasticsearch.xpack.prelert.job.persistence.JobProvider; import org.elasticsearch.xpack.prelert.job.persistence.QueryPage; -import org.elasticsearch.xpack.prelert.scheduler.SchedulerStatus; import org.elasticsearch.xpack.prelert.utils.ExceptionsHelper; import java.io.IOException; @@ -54,7 +53,6 @@ public class GetJobsStatsAction extends Action schedulerStatus = prelertMetadata.getSchedulerStatusByJobId(job.getId()); - jobsStats.add(new Response.JobStats(job.getId(), dataCounts, modelSizeStats, status, schedulerStatus.orElse(null))); + jobsStats.add(new Response.JobStats(job.getId(), dataCounts, modelSizeStats, status)); } QueryPage jobsStatsPage = new QueryPage<>(jobsStats, jobsStats.size(), Job.RESULTS_FIELD); diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/action/GetSchedulersAction.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/action/GetSchedulersAction.java new file mode 100644 index 00000000000..c72ed3d6e31 --- /dev/null +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/action/GetSchedulersAction.java @@ -0,0 +1,237 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.prelert.action; + +import org.elasticsearch.action.Action; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.action.support.master.MasterNodeReadOperationRequestBuilder; +import org.elasticsearch.action.support.master.MasterNodeReadRequest; +import org.elasticsearch.action.support.master.TransportMasterNodeReadAction; +import org.elasticsearch.client.ElasticsearchClient; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.block.ClusterBlockException; +import org.elasticsearch.cluster.block.ClusterBlockLevel; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.StatusToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xpack.prelert.job.metadata.PrelertMetadata; +import org.elasticsearch.xpack.prelert.job.persistence.QueryPage; +import org.elasticsearch.xpack.prelert.scheduler.Scheduler; +import org.elasticsearch.xpack.prelert.scheduler.SchedulerConfig; +import org.elasticsearch.xpack.prelert.utils.ExceptionsHelper; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class GetSchedulersAction extends Action { + + public static final GetSchedulersAction INSTANCE = new GetSchedulersAction(); + public static final String NAME = "cluster:admin/prelert/schedulers/get"; + + private static final String ALL = "_all"; + + private GetSchedulersAction() { + super(NAME); + } + + @Override + public RequestBuilder newRequestBuilder(ElasticsearchClient client) { + return new RequestBuilder(client, this); + } + + @Override + public Response newResponse() { + return new Response(); + } + + public static class Request extends MasterNodeReadRequest { + + private String schedulerId; + + public Request(String schedulerId) { + this.schedulerId = ExceptionsHelper.requireNonNull(schedulerId, SchedulerConfig.ID.getPreferredName()); + } + + Request() {} + + public String getSchedulerId() { + return schedulerId; + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + @Override + public void readFrom(StreamInput in) throws IOException { + super.readFrom(in); + schedulerId = in.readString(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeString(schedulerId); + } + + @Override + public int hashCode() { + return Objects.hash(schedulerId); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Request other = (Request) obj; + return Objects.equals(schedulerId, other.schedulerId); + } + } + + public static class RequestBuilder extends MasterNodeReadOperationRequestBuilder { + + public RequestBuilder(ElasticsearchClient client, GetSchedulersAction action) { + super(client, action, new Request()); + } + } + + public static class Response extends ActionResponse implements StatusToXContent { + + private QueryPage schedulers; + + public Response(QueryPage schedulers) { + this.schedulers = schedulers; + } + + public Response() {} + + public QueryPage getResponse() { + return schedulers; + } + + @Override + public void readFrom(StreamInput in) throws IOException { + super.readFrom(in); + schedulers = new QueryPage<>(in, SchedulerConfig::new); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + schedulers.writeTo(out); + } + + @Override + public RestStatus status() { + return schedulers.count() == 0 ? RestStatus.NOT_FOUND : RestStatus.OK; + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + return schedulers.doXContentBody(builder, params); + } + + @Override + public int hashCode() { + return Objects.hash(schedulers); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Response other = (Response) obj; + return Objects.equals(schedulers, other.schedulers); + } + + @SuppressWarnings("deprecation") + @Override + public final String toString() { + try { + XContentBuilder builder = XContentFactory.jsonBuilder(); + builder.prettyPrint(); + builder.startObject(); + toXContent(builder, EMPTY_PARAMS); + builder.endObject(); + return builder.string(); + } catch (Exception e) { + // So we have a stack trace logged somewhere + return "{ \"error\" : \"" + org.elasticsearch.ExceptionsHelper.detailedMessage(e) + "\"}"; + } + } + } + + public static class TransportAction extends TransportMasterNodeReadAction { + + @Inject + public TransportAction(Settings settings, TransportService transportService, ClusterService clusterService, + ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) { + super(settings, GetSchedulersAction.NAME, transportService, clusterService, threadPool, actionFilters, + indexNameExpressionResolver, Request::new); + } + + @Override + protected String executor() { + return ThreadPool.Names.SAME; + } + + @Override + protected Response newResponse() { + return new Response(); + } + + @Override + protected void masterOperation(Request request, ClusterState state, ActionListener listener) throws Exception { + logger.debug("Get scheduler '{}'", request.getSchedulerId()); + + QueryPage response = null; + PrelertMetadata prelertMetadata = state.metaData().custom(PrelertMetadata.TYPE); + if (ALL.equals(request.getSchedulerId())) { + List schedulerConfigs = prelertMetadata.getSchedulers().values().stream().map( + s -> s.getConfig()).collect(Collectors.toList()); + response = new QueryPage<>(schedulerConfigs, schedulerConfigs.size(), Scheduler.RESULTS_FIELD); + } else { + Scheduler scheduler = prelertMetadata.getScheduler(request.getSchedulerId()); + if (scheduler == null) { + throw ExceptionsHelper.missingSchedulerException(request.getSchedulerId()); + } + response = new QueryPage<>(Collections.singletonList(scheduler.getConfig()), 1, Scheduler.RESULTS_FIELD); + } + + listener.onResponse(new Response(response)); + } + + @Override + protected ClusterBlockException checkBlock(Request request, ClusterState state) { + return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ); + } + } +} diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/action/GetSchedulersStatsAction.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/action/GetSchedulersStatsAction.java new file mode 100644 index 00000000000..99dff4de040 --- /dev/null +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/action/GetSchedulersStatsAction.java @@ -0,0 +1,300 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.prelert.action; + +import org.elasticsearch.action.Action; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.action.support.master.MasterNodeReadOperationRequestBuilder; +import org.elasticsearch.action.support.master.MasterNodeReadRequest; +import org.elasticsearch.action.support.master.TransportMasterNodeReadAction; +import org.elasticsearch.client.ElasticsearchClient; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.block.ClusterBlockException; +import org.elasticsearch.cluster.block.ClusterBlockLevel; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.StatusToXContent; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xpack.prelert.job.metadata.PrelertMetadata; +import org.elasticsearch.xpack.prelert.job.persistence.QueryPage; +import org.elasticsearch.xpack.prelert.scheduler.Scheduler; +import org.elasticsearch.xpack.prelert.scheduler.SchedulerConfig; +import org.elasticsearch.xpack.prelert.scheduler.SchedulerStatus; +import org.elasticsearch.xpack.prelert.utils.ExceptionsHelper; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; + +public class GetSchedulersStatsAction extends Action { + + public static final GetSchedulersStatsAction INSTANCE = new GetSchedulersStatsAction(); + public static final String NAME = "cluster:admin/prelert/schedulers/stats/get"; + + private static final String ALL = "_all"; + private static final String STATUS = "status"; + + private GetSchedulersStatsAction() { + super(NAME); + } + + @Override + public RequestBuilder newRequestBuilder(ElasticsearchClient client) { + return new RequestBuilder(client, this); + } + + @Override + public Response newResponse() { + return new Response(); + } + + public static class Request extends MasterNodeReadRequest { + + private String schedulerId; + + public Request(String schedulerId) { + this.schedulerId = ExceptionsHelper.requireNonNull(schedulerId, SchedulerConfig.ID.getPreferredName()); + } + + Request() {} + + public String getSchedulerId() { + return schedulerId; + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + @Override + public void readFrom(StreamInput in) throws IOException { + super.readFrom(in); + schedulerId = in.readString(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeString(schedulerId); + } + + @Override + public int hashCode() { + return Objects.hash(schedulerId); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Request other = (Request) obj; + return Objects.equals(schedulerId, other.schedulerId); + } + } + + public static class RequestBuilder extends MasterNodeReadOperationRequestBuilder { + + public RequestBuilder(ElasticsearchClient client, GetSchedulersStatsAction action) { + super(client, action, new Request()); + } + } + + public static class Response extends ActionResponse implements StatusToXContent { + + public static class SchedulerStats implements ToXContent, Writeable { + + private final String schedulerId; + private final SchedulerStatus schedulerStatus; + + SchedulerStats(String schedulerId, SchedulerStatus schedulerStatus) { + this.schedulerId = Objects.requireNonNull(schedulerId); + this.schedulerStatus = Objects.requireNonNull(schedulerStatus); + } + + SchedulerStats(StreamInput in) throws IOException { + schedulerId = in.readString(); + schedulerStatus = SchedulerStatus.fromStream(in); + } + + public String getSchedulerId() { + return schedulerId; + } + + public SchedulerStatus getSchedulerStatus() { + return schedulerStatus; + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field(SchedulerConfig.ID.getPreferredName(), schedulerId); + builder.field(STATUS, schedulerStatus); + builder.endObject(); + + return builder; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(schedulerId); + schedulerStatus.writeTo(out); + } + + @Override + public int hashCode() { + return Objects.hash(schedulerId, schedulerStatus); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + GetSchedulersStatsAction.Response.SchedulerStats other = (GetSchedulersStatsAction.Response.SchedulerStats) obj; + return Objects.equals(schedulerId, other.schedulerId) && Objects.equals(this.schedulerStatus, other.schedulerStatus); + } + } + + private QueryPage schedulersStats; + + public Response(QueryPage schedulersStats) { + this.schedulersStats = schedulersStats; + } + + public Response() {} + + public QueryPage getResponse() { + return schedulersStats; + } + + @Override + public void readFrom(StreamInput in) throws IOException { + super.readFrom(in); + schedulersStats = new QueryPage<>(in, SchedulerStats::new); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + schedulersStats.writeTo(out); + } + + @Override + public RestStatus status() { + return schedulersStats.count() == 0 ? RestStatus.NOT_FOUND : RestStatus.OK; + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + return schedulersStats.doXContentBody(builder, params); + } + + @Override + public int hashCode() { + return Objects.hash(schedulersStats); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Response other = (Response) obj; + return Objects.equals(schedulersStats, other.schedulersStats); + } + + @SuppressWarnings("deprecation") + @Override + public final String toString() { + try { + XContentBuilder builder = XContentFactory.jsonBuilder(); + builder.prettyPrint(); + builder.startObject(); + toXContent(builder, EMPTY_PARAMS); + builder.endObject(); + return builder.string(); + } catch (Exception e) { + // So we have a stack trace logged somewhere + return "{ \"error\" : \"" + org.elasticsearch.ExceptionsHelper.detailedMessage(e) + "\"}"; + } + } + } + + public static class TransportAction extends TransportMasterNodeReadAction { + + @Inject + public TransportAction(Settings settings, TransportService transportService, ClusterService clusterService, + ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) { + super(settings, GetSchedulersStatsAction.NAME, transportService, clusterService, threadPool, actionFilters, + indexNameExpressionResolver, Request::new); + } + + @Override + protected String executor() { + return ThreadPool.Names.SAME; + } + + @Override + protected Response newResponse() { + return new Response(); + } + + @Override + protected void masterOperation(Request request, ClusterState state, ActionListener listener) throws Exception { + logger.debug("Get stats for scheduler '{}'", request.getSchedulerId()); + + List stats = new ArrayList<>(); + PrelertMetadata prelertMetadata = state.metaData().custom(PrelertMetadata.TYPE); + if (ALL.equals(request.getSchedulerId())) { + Collection schedulers = prelertMetadata.getSchedulers().values(); + for (Scheduler scheduler : schedulers) { + stats.add(new Response.SchedulerStats(scheduler.getId(), scheduler.getStatus())); + } + } else { + Scheduler scheduler = prelertMetadata.getScheduler(request.getSchedulerId()); + if (scheduler == null) { + throw ExceptionsHelper.missingSchedulerException(request.getSchedulerId()); + } + stats.add(new Response.SchedulerStats(scheduler.getId(), scheduler.getStatus())); + } + + QueryPage statsPage = new QueryPage<>(stats, stats.size(), Scheduler.RESULTS_FIELD); + listener.onResponse(new Response(statsPage)); + } + + @Override + protected ClusterBlockException checkBlock(Request request, ClusterState state) { + return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ); + } + } +} diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/job/messages/Messages.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/job/messages/Messages.java index dad7869a901..6c3a22c746f 100644 --- a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/job/messages/Messages.java +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/job/messages/Messages.java @@ -188,7 +188,6 @@ public final class Messages { public static final String JOB_DATA_CONCURRENT_USE_UPDATE = "job.data.concurrent.use.update"; public static final String JOB_DATA_CONCURRENT_USE_UPLOAD = "job.data.concurrent.use.upload"; - public static final String SCHEDULER_CONFIG_FIELD_NOT_SUPPORTED = "scheduler.config.field.not.supported"; public static final String SCHEDULER_CONFIG_INVALID_OPTION_VALUE = "scheduler.config.invalid.option.value"; public static final String SCHEDULER_DOES_NOT_SUPPORT_JOB_WITH_LATENCY = "scheduler.does.not.support.job.with.latency"; diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/job/metadata/PrelertMetadata.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/job/metadata/PrelertMetadata.java index 197d1d629f0..7f8e4a79a3f 100644 --- a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/job/metadata/PrelertMetadata.java +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/job/metadata/PrelertMetadata.java @@ -307,7 +307,7 @@ public class PrelertMetadata implements MetaData.Custom { public Builder removeScheduler(String schedulerId) { Scheduler scheduler = schedulers.get(schedulerId); if (scheduler == null) { - throw new ResourceNotFoundException(Messages.getMessage(Messages.SCHEDULER_NOT_FOUND, schedulerId)); + throw ExceptionsHelper.missingSchedulerException(schedulerId); } if (scheduler.getStatus() != SchedulerStatus.STOPPED) { String msg = Messages.getMessage(Messages.SCHEDULER_CANNOT_DELETE_IN_CURRENT_STATE, schedulerId, scheduler.getStatus()); @@ -400,7 +400,7 @@ public class PrelertMetadata implements MetaData.Custom { public Builder updateSchedulerStatus(String schedulerId, SchedulerStatus newStatus) { Scheduler scheduler = schedulers.get(schedulerId); if (scheduler == null) { - throw new ResourceNotFoundException(Messages.getMessage(Messages.SCHEDULER_NOT_FOUND, schedulerId)); + throw ExceptionsHelper.missingSchedulerException(schedulerId); } SchedulerStatus currentStatus = scheduler.getStatus(); diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/rest/schedulers/RestGetSchedulersAction.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/rest/schedulers/RestGetSchedulersAction.java new file mode 100644 index 00000000000..8e6e7a8661e --- /dev/null +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/rest/schedulers/RestGetSchedulersAction.java @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.prelert.rest.schedulers; + +import org.elasticsearch.client.node.NodeClient; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.rest.BaseRestHandler; +import org.elasticsearch.rest.RestController; +import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.action.RestStatusToXContentListener; +import org.elasticsearch.xpack.prelert.PrelertPlugin; +import org.elasticsearch.xpack.prelert.action.GetSchedulersAction; +import org.elasticsearch.xpack.prelert.scheduler.SchedulerConfig; + +import java.io.IOException; + +public class RestGetSchedulersAction extends BaseRestHandler { + + private final GetSchedulersAction.TransportAction transportGetSchedulersAction; + + @Inject + public RestGetSchedulersAction(Settings settings, RestController controller, + GetSchedulersAction.TransportAction transportGetSchedulersAction) { + super(settings); + this.transportGetSchedulersAction = transportGetSchedulersAction; + + controller.registerHandler(RestRequest.Method.GET, PrelertPlugin.BASE_PATH + + "schedulers/{" + SchedulerConfig.ID.getPreferredName() + "}", this); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient client) throws IOException { + GetSchedulersAction.Request request = new GetSchedulersAction.Request(restRequest.param(SchedulerConfig.ID.getPreferredName())); + return channel -> transportGetSchedulersAction.execute(request, new RestStatusToXContentListener<>(channel)); + } +} diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/rest/schedulers/RestGetSchedulersStatsAction.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/rest/schedulers/RestGetSchedulersStatsAction.java new file mode 100644 index 00000000000..1a536bf301d --- /dev/null +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/rest/schedulers/RestGetSchedulersStatsAction.java @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.prelert.rest.schedulers; + +import org.elasticsearch.client.node.NodeClient; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.rest.BaseRestHandler; +import org.elasticsearch.rest.RestController; +import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.action.RestStatusToXContentListener; +import org.elasticsearch.xpack.prelert.PrelertPlugin; +import org.elasticsearch.xpack.prelert.action.GetSchedulersStatsAction; +import org.elasticsearch.xpack.prelert.scheduler.SchedulerConfig; + +import java.io.IOException; + +public class RestGetSchedulersStatsAction extends BaseRestHandler { + + private final GetSchedulersStatsAction.TransportAction transportGetSchedulersStatsAction; + + @Inject + public RestGetSchedulersStatsAction(Settings settings, RestController controller, + GetSchedulersStatsAction.TransportAction transportGetSchedulersStatsAction) { + super(settings); + this.transportGetSchedulersStatsAction = transportGetSchedulersStatsAction; + + controller.registerHandler(RestRequest.Method.GET, PrelertPlugin.BASE_PATH + + "schedulers/{" + SchedulerConfig.ID.getPreferredName() + "}/_stats", this); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient client) throws IOException { + GetSchedulersStatsAction.Request request = new GetSchedulersStatsAction.Request( + restRequest.param(SchedulerConfig.ID.getPreferredName())); + return channel -> transportGetSchedulersStatsAction.execute(request, new RestStatusToXContentListener<>(channel)); + } +} diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/scheduler/ScheduledJobRunner.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/scheduler/ScheduledJobRunner.java index 45d0f96f654..612c02713b0 100644 --- a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/scheduler/ScheduledJobRunner.java +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/scheduler/ScheduledJobRunner.java @@ -134,7 +134,7 @@ public class ScheduledJobRunner extends AbstractComponent { public static void validate(String schedulerId, PrelertMetadata prelertMetadata) { Scheduler scheduler = prelertMetadata.getScheduler(schedulerId); if (scheduler == null) { - throw new ResourceNotFoundException(Messages.getMessage(Messages.SCHEDULER_NOT_FOUND, schedulerId)); + throw ExceptionsHelper.missingSchedulerException(schedulerId); } Job job = prelertMetadata.getJobs().get(scheduler.getJobId()); if (job == null) { diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/scheduler/Scheduler.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/scheduler/Scheduler.java index 2109524abd2..8c688b00618 100644 --- a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/scheduler/Scheduler.java +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/scheduler/Scheduler.java @@ -25,6 +25,9 @@ public class Scheduler extends AbstractDiffable implements ToXContent public static final Scheduler PROTO = new Scheduler(null, null); + // Used for QueryPage + public static final ParseField RESULTS_FIELD = new ParseField("schedulers"); + public static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("scheduler", a -> new Scheduler((SchedulerConfig) a[0], (SchedulerStatus) a[1])); diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/scheduler/SchedulerConfig.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/scheduler/SchedulerConfig.java index f834ed019fa..28335639b06 100644 --- a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/scheduler/SchedulerConfig.java +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/scheduler/SchedulerConfig.java @@ -419,7 +419,6 @@ public class SchedulerConfig extends ToXContentToBytes implements Writeable { private Map query = null; private Map aggregations = null; private Map scriptFields = null; - private Boolean retrieveWholeSource; private Integer scrollSize; public Builder() { @@ -427,7 +426,6 @@ public class SchedulerConfig extends ToXContentToBytes implements Writeable { query.put(MATCH_ALL_ES_QUERY, new HashMap()); setQuery(query); setQueryDelay(DEFAULT_ELASTICSEARCH_QUERY_DELAY); - setRetrieveWholeSource(false); setScrollSize(DEFAULT_SCROLL_SIZE); } @@ -499,10 +497,6 @@ public class SchedulerConfig extends ToXContentToBytes implements Writeable { this.scriptFields = Objects.requireNonNull(scriptFields); } - public void setRetrieveWholeSource(boolean retrieveWholeSource) { - this.retrieveWholeSource = retrieveWholeSource; - } - public void setScrollSize(int scrollSize) { if (scrollSize < 0) { String msg = Messages.getMessage(Messages.SCHEDULER_CONFIG_INVALID_OPTION_VALUE, @@ -524,11 +518,6 @@ public class SchedulerConfig extends ToXContentToBytes implements Writeable { if (types == null || types.isEmpty() || types.contains(null) || types.contains("")) { throw invalidOptionValue(TYPES.getPreferredName(), types); } - if (Boolean.TRUE.equals(retrieveWholeSource)) { - if (scriptFields != null) { - throw notSupportedValue(SCRIPT_FIELDS, Messages.SCHEDULER_CONFIG_FIELD_NOT_SUPPORTED); - } - } return new SchedulerConfig(id, jobId, queryDelay, frequency, indexes, types, query, aggregations, scriptFields, scrollSize); } diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/utils/ExceptionsHelper.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/utils/ExceptionsHelper.java index 24970c9d717..dc451ad4b3f 100644 --- a/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/utils/ExceptionsHelper.java +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/prelert/utils/ExceptionsHelper.java @@ -23,6 +23,10 @@ public class ExceptionsHelper { throw new ResourceAlreadyExistsException(Messages.getMessage(Messages.JOB_CONFIG_ID_ALREADY_TAKEN, jobId)); } + public static ResourceNotFoundException missingSchedulerException(String schedulerId) { + throw new ResourceNotFoundException(Messages.getMessage(Messages.SCHEDULER_NOT_FOUND, schedulerId)); + } + public static ElasticsearchException serverError(String msg) { return new ElasticsearchException(msg); } diff --git a/elasticsearch/src/main/resources/org/elasticsearch/xpack/prelert/job/messages/prelert_messages.properties b/elasticsearch/src/main/resources/org/elasticsearch/xpack/prelert/job/messages/prelert_messages.properties index 2b9e63b60d8..4c4f0c41462 100644 --- a/elasticsearch/src/main/resources/org/elasticsearch/xpack/prelert/job/messages/prelert_messages.properties +++ b/elasticsearch/src/main/resources/org/elasticsearch/xpack/prelert/job/messages/prelert_messages.properties @@ -137,7 +137,6 @@ job.config.transform.output.name.used.more.than.once = Transform output name ''{ job.config.transform.unknown.type = Unknown TransformType ''{0}'' job.config.unknown.function = Unknown function ''{0}'' -scheduler.config.field.not.supported = Scheduler configuration field {0} not supported scheduler.config.invalid.option.value = Invalid {0} value ''{1}'' in scheduler configuration scheduler.does.not.support.job.with.latency = A job configured with scheduler cannot support latency diff --git a/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobActionRequestTests.java b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobsActionRequestTests.java similarity index 88% rename from elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobActionRequestTests.java rename to elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobsActionRequestTests.java index 24ca47efcc0..4131620f2c7 100644 --- a/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobActionRequestTests.java +++ b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobsActionRequestTests.java @@ -9,7 +9,7 @@ import org.elasticsearch.xpack.prelert.action.GetJobsAction.Request; import org.elasticsearch.xpack.prelert.job.Job; import org.elasticsearch.xpack.prelert.support.AbstractStreamableTestCase; -public class GetJobActionRequestTests extends AbstractStreamableTestCase { +public class GetJobsActionRequestTests extends AbstractStreamableTestCase { @Override protected Request createTestInstance() { diff --git a/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobActionResponseTests.java b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobsActionResponseTests.java similarity index 97% rename from elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobActionResponseTests.java rename to elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobsActionResponseTests.java index 4a6dd924667..041b5c3a148 100644 --- a/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobActionResponseTests.java +++ b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobsActionResponseTests.java @@ -24,7 +24,7 @@ import java.util.Date; import java.util.List; import java.util.Map; -public class GetJobActionResponseTests extends AbstractStreamableTestCase { +public class GetJobsActionResponseTests extends AbstractStreamableTestCase { @Override protected Response createTestInstance() { diff --git a/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobsStatsActionResponseTests.java b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobsStatsActionResponseTests.java index e5acd2edafc..fc623a6e01a 100644 --- a/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobsStatsActionResponseTests.java +++ b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetJobsStatsActionResponseTests.java @@ -41,12 +41,7 @@ public class GetJobsStatsActionResponseTests extends AbstractStreamableTestCase< } JobStatus jobStatus = randomFrom(EnumSet.allOf(JobStatus.class)); - SchedulerStatus schedulerStatus = null; - if (randomBoolean()) { - schedulerStatus = randomFrom(SchedulerStatus.values()); - } - - Response.JobStats jobStats = new Response.JobStats(jobId, dataCounts, sizeStats, jobStatus, schedulerStatus); + Response.JobStats jobStats = new Response.JobStats(jobId, dataCounts, sizeStats, jobStatus); jobStatsList.add(jobStats); } diff --git a/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersActionRequestTests.java b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersActionRequestTests.java new file mode 100644 index 00000000000..082ba821d3c --- /dev/null +++ b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersActionRequestTests.java @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.prelert.action; + +import org.elasticsearch.xpack.prelert.action.GetSchedulersAction.Request; +import org.elasticsearch.xpack.prelert.job.Job; +import org.elasticsearch.xpack.prelert.support.AbstractStreamableTestCase; + +public class GetSchedulersActionRequestTests extends AbstractStreamableTestCase { + + @Override + protected Request createTestInstance() { + return new Request(randomBoolean() ? Job.ALL : randomAsciiOfLengthBetween(1, 20)); + } + + @Override + protected Request createBlankInstance() { + return new Request(); + } + +} diff --git a/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersActionResponseTests.java b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersActionResponseTests.java new file mode 100644 index 00000000000..7f4c8f9c9e2 --- /dev/null +++ b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersActionResponseTests.java @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.prelert.action; + +import org.elasticsearch.xpack.prelert.action.GetSchedulersAction.Response; +import org.elasticsearch.xpack.prelert.job.persistence.QueryPage; +import org.elasticsearch.xpack.prelert.scheduler.Scheduler; +import org.elasticsearch.xpack.prelert.scheduler.SchedulerConfig; +import org.elasticsearch.xpack.prelert.scheduler.SchedulerConfigTests; +import org.elasticsearch.xpack.prelert.support.AbstractStreamableTestCase; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class GetSchedulersActionResponseTests extends AbstractStreamableTestCase { + + @Override + protected Response createTestInstance() { + final Response result; + + int listSize = randomInt(10); + List schedulerList = new ArrayList<>(listSize); + for (int j = 0; j < listSize; j++) { + String schedulerId = SchedulerConfigTests.randomValidSchedulerId(); + String jobId = randomAsciiOfLength(10); + SchedulerConfig.Builder schedulerConfig = new SchedulerConfig.Builder(schedulerId, jobId); + schedulerConfig.setIndexes(randomSubsetOf(2, Arrays.asList("index-1", "index-2", "index-3"))); + schedulerConfig.setTypes(randomSubsetOf(2, Arrays.asList("type-1", "type-2", "type-3"))); + schedulerConfig.setFrequency(randomPositiveLong()); + schedulerConfig.setQueryDelay(randomPositiveLong()); + if (randomBoolean()) { + schedulerConfig.setQuery(Collections.singletonMap(randomAsciiOfLength(10), randomAsciiOfLength(10))); + } + if (randomBoolean()) { + schedulerConfig.setScriptFields(Collections.singletonMap(randomAsciiOfLength(10), randomAsciiOfLength(10))); + } + if (randomBoolean()) { + schedulerConfig.setScrollSize(randomIntBetween(0, Integer.MAX_VALUE)); + } + if (randomBoolean()) { + schedulerConfig.setAggregations(Collections.singletonMap(randomAsciiOfLength(10), randomAsciiOfLength(10))); + } + + schedulerList.add(schedulerConfig.build()); + } + + result = new Response(new QueryPage<>(schedulerList, schedulerList.size(), Scheduler.RESULTS_FIELD)); + + return result; + } + + @Override + protected Response createBlankInstance() { + return new Response(); + } + +} diff --git a/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersStatsActionRequestTests.java b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersStatsActionRequestTests.java new file mode 100644 index 00000000000..851407006a5 --- /dev/null +++ b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersStatsActionRequestTests.java @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.prelert.action; + +import org.elasticsearch.xpack.prelert.action.GetSchedulersStatsAction.Request; +import org.elasticsearch.xpack.prelert.job.Job; +import org.elasticsearch.xpack.prelert.support.AbstractStreamableTestCase; + +public class GetSchedulersStatsActionRequestTests extends AbstractStreamableTestCase { + + @Override + protected Request createTestInstance() { + return new Request(randomBoolean() ? Job.ALL : randomAsciiOfLengthBetween(1, 20)); + } + + @Override + protected Request createBlankInstance() { + return new Request(); + } + +} diff --git a/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersStatsActionResponseTests.java b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersStatsActionResponseTests.java new file mode 100644 index 00000000000..881ce3d067b --- /dev/null +++ b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/action/GetSchedulersStatsActionResponseTests.java @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.prelert.action; + +import org.elasticsearch.xpack.prelert.action.GetSchedulersStatsAction.Response; +import org.elasticsearch.xpack.prelert.job.persistence.QueryPage; +import org.elasticsearch.xpack.prelert.scheduler.Scheduler; +import org.elasticsearch.xpack.prelert.scheduler.SchedulerStatus; +import org.elasticsearch.xpack.prelert.support.AbstractStreamableTestCase; + +import java.util.ArrayList; +import java.util.List; + +public class GetSchedulersStatsActionResponseTests extends AbstractStreamableTestCase { + + @Override + protected Response createTestInstance() { + final Response result; + + int listSize = randomInt(10); + List schedulerStatsList = new ArrayList<>(listSize); + for (int j = 0; j < listSize; j++) { + String schedulerId = randomAsciiOfLength(10); + SchedulerStatus schedulerStatus = randomFrom(SchedulerStatus.values()); + + Response.SchedulerStats schedulerStats = new Response.SchedulerStats(schedulerId, schedulerStatus); + schedulerStatsList.add(schedulerStats); + } + + result = new Response(new QueryPage<>(schedulerStatsList, schedulerStatsList.size(), Scheduler.RESULTS_FIELD)); + + return result; + } + + @Override + protected Response createBlankInstance() { + return new Response(); + } + +} diff --git a/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/scheduler/SchedulerConfigTests.java b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/scheduler/SchedulerConfigTests.java index 1d444cd5ff9..d9a18bae8e0 100644 --- a/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/scheduler/SchedulerConfigTests.java +++ b/elasticsearch/src/test/java/org/elasticsearch/xpack/prelert/scheduler/SchedulerConfigTests.java @@ -34,10 +34,7 @@ public class SchedulerConfigTests extends AbstractSerializingTestCase()); expectedSchedulerConfig.setQuery(defaultQuery); expectedSchedulerConfig.setQueryDelay(60L); - expectedSchedulerConfig.setRetrieveWholeSource(false); expectedSchedulerConfig.setScrollSize(1000); SchedulerConfig.Builder defaultedSchedulerConfig = new SchedulerConfig.Builder("scheduler1", "job1"); defaultedSchedulerConfig.setIndexes(Arrays.asList("index")); @@ -266,7 +262,7 @@ public class SchedulerConfigTests extends AbstractSerializingTestCase()), conf.build().getQuery()); } - public void testCheckValid_GivenScriptFieldsNotWholeSource() throws IOException { + public void testCheckValid_GivenScriptFields() throws IOException { SchedulerConfig.Builder conf = new SchedulerConfig.Builder("scheduler1", "job1"); conf.setIndexes(Arrays.asList("myindex")); conf.setTypes(Arrays.asList("mytype")); @@ -274,22 +270,9 @@ public class SchedulerConfigTests extends AbstractSerializingTestCase conf.setIndexes(null)); diff --git a/elasticsearch/src/test/resources/rest-api-spec/api/xpack.prelert.get_schedulers.json b/elasticsearch/src/test/resources/rest-api-spec/api/xpack.prelert.get_schedulers.json new file mode 100644 index 00000000000..fc0fc692fb9 --- /dev/null +++ b/elasticsearch/src/test/resources/rest-api-spec/api/xpack.prelert.get_schedulers.json @@ -0,0 +1,19 @@ +{ + "xpack.prelert.get_schedulers": { + "methods": [ "GET"], + "url": { + "path": "/_xpack/prelert/schedulers/{scheduler_id}", + "paths": [ + "/_xpack/prelert/schedulers/{scheduler_id}" + ], + "parts": { + "scheduler_id": { + "type": "string", + "required": true, + "description": "The ID of the schedulers to fetch" + } + } + }, + "body": null + } +} diff --git a/elasticsearch/src/test/resources/rest-api-spec/api/xpack.prelert.get_schedulers_stats.json b/elasticsearch/src/test/resources/rest-api-spec/api/xpack.prelert.get_schedulers_stats.json new file mode 100644 index 00000000000..217d7415b62 --- /dev/null +++ b/elasticsearch/src/test/resources/rest-api-spec/api/xpack.prelert.get_schedulers_stats.json @@ -0,0 +1,19 @@ +{ + "xpack.prelert.get_schedulers_stats": { + "methods": [ "GET"], + "url": { + "path": "/_xpack/prelert/schedulers/{scheduler_id}/_stats", + "paths": [ + "/_xpack/prelert/schedulers/{scheduler_id}/_stats" + ], + "parts": { + "scheduler_id": { + "type": "string", + "required": true, + "description": "The ID of the schedulers stats to fetch" + } + } + }, + "body": null + } +} diff --git a/elasticsearch/src/test/resources/rest-api-spec/test/get_schedulers.yaml b/elasticsearch/src/test/resources/rest-api-spec/test/get_schedulers.yaml new file mode 100644 index 00000000000..9978871b411 --- /dev/null +++ b/elasticsearch/src/test/resources/rest-api-spec/test/get_schedulers.yaml @@ -0,0 +1,87 @@ +setup: + - do: + xpack.prelert.put_job: + body: > + { + "job_id":"job-1", + "analysis_config" : { + "bucket_span":3600, + "detectors" :[{"function":"count"}] + }, + "data_description" : { + "format":"ELASTICSEARCH", + "time_field":"time", + "time_format":"epoch" + } + } + + - do: + xpack.prelert.put_job: + body: > + { + "job_id":"job-2", + "analysis_config" : { + "bucket_span":3600, + "detectors" :[{"function":"count"}] + }, + "data_description" : { + "format":"ELASTICSEARCH", + "time_field":"time", + "time_format":"epoch" + } + } + + - do: + xpack.prelert.put_scheduler: + scheduler_id: scheduler-1 + body: > + { + "job_id":"job-1", + "indexes":["index-1"], + "types":["type-1"] + } + + - do: + xpack.prelert.put_scheduler: + scheduler_id: scheduler-2 + body: > + { + "job_id":"job-2", + "indexes":["index-2"], + "types":["type-2"] + } + +--- +"Test get scheduler given missing scheduler_id": + + - do: + catch: missing + xpack.prelert.get_schedulers: + scheduler_id: missing-scheduler + +--- +"Test get single scheduler": + + - do: + xpack.prelert.get_schedulers: + scheduler_id: scheduler-1 + - match: { schedulers.0.scheduler_id: "scheduler-1"} + - match: { schedulers.0.job_id: "job-1"} + + - do: + xpack.prelert.get_schedulers: + scheduler_id: scheduler-2 + - match: { schedulers.0.scheduler_id: "scheduler-2"} + - match: { schedulers.0.job_id: "job-2"} + +--- +"Test get all schedulers": + + - do: + xpack.prelert.get_schedulers: + scheduler_id: _all + - match: { count: 2 } + - match: { schedulers.0.scheduler_id: "scheduler-1"} + - match: { schedulers.0.job_id: "job-1"} + - match: { schedulers.1.scheduler_id: "scheduler-2"} + - match: { schedulers.1.job_id: "job-2"} diff --git a/elasticsearch/src/test/resources/rest-api-spec/test/get_schedulers_stats.yaml b/elasticsearch/src/test/resources/rest-api-spec/test/get_schedulers_stats.yaml new file mode 100644 index 00000000000..8eabeddf0bf --- /dev/null +++ b/elasticsearch/src/test/resources/rest-api-spec/test/get_schedulers_stats.yaml @@ -0,0 +1,87 @@ +setup: + - do: + xpack.prelert.put_job: + body: > + { + "job_id":"job-1", + "analysis_config" : { + "bucket_span":3600, + "detectors" :[{"function":"count"}] + }, + "data_description" : { + "format":"ELASTICSEARCH", + "time_field":"time", + "time_format":"epoch" + } + } + + - do: + xpack.prelert.put_job: + body: > + { + "job_id":"job-2", + "analysis_config" : { + "bucket_span":3600, + "detectors" :[{"function":"count"}] + }, + "data_description" : { + "format":"ELASTICSEARCH", + "time_field":"time", + "time_format":"epoch" + } + } + + - do: + xpack.prelert.put_scheduler: + scheduler_id: scheduler-1 + body: > + { + "job_id":"job-1", + "indexes":["index-1"], + "types":["type-1"] + } + + - do: + xpack.prelert.put_scheduler: + scheduler_id: scheduler-2 + body: > + { + "job_id":"job-2", + "indexes":["index-2"], + "types":["type-2"] + } + +--- +"Test get scheduler stats given missing scheduler_id": + + - do: + catch: missing + xpack.prelert.get_schedulers_stats: + scheduler_id: missing-scheduler + +--- +"Test get single scheduler stats": + + - do: + xpack.prelert.get_schedulers_stats: + scheduler_id: scheduler-1 + - match: { schedulers.0.scheduler_id: "scheduler-1"} + - match: { schedulers.0.status: "STOPPED"} + + - do: + xpack.prelert.get_schedulers_stats: + scheduler_id: scheduler-2 + - match: { schedulers.0.scheduler_id: "scheduler-2"} + - match: { schedulers.0.status: "STOPPED"} + +--- +"Test get all schedulers stats": + + - do: + xpack.prelert.get_schedulers_stats: + scheduler_id: _all + - match: { count: 2 } + - match: { schedulers.0.scheduler_id: "scheduler-1"} + - match: { schedulers.0.status: "STOPPED"} + - match: { schedulers.1.scheduler_id: "scheduler-2"} + - match: { schedulers.1.status: "STOPPED"} diff --git a/elasticsearch/src/test/resources/rest-api-spec/test/jobs_get_stats.yaml b/elasticsearch/src/test/resources/rest-api-spec/test/jobs_get_stats.yaml index 9e6f9419e3d..73c44c177ab 100644 --- a/elasticsearch/src/test/resources/rest-api-spec/test/jobs_get_stats.yaml +++ b/elasticsearch/src/test/resources/rest-api-spec/test/jobs_get_stats.yaml @@ -89,7 +89,6 @@ setup: - match: { jobs.0.data_counts.input_field_count: 4 } - match: { jobs.0.model_size_stats.model_bytes: 100 } - match: { jobs.0.status: OPENED } - - is_false: jobs.0.scheduler_status --- "Test get job stats of scheduled job that has not received and data": @@ -101,7 +100,6 @@ setup: - match: { jobs.0.data_counts.processed_record_count: 0 } - is_false: jobs.0.model_size_stats - match: { jobs.0.status: OPENED } - - match: { jobs.0.scheduler_status: STOPPED } --- "Test get job stats given missing job": diff --git a/elasticsearch/src/test/resources/rest-api-spec/test/start_stop_scheduler.yaml b/elasticsearch/src/test/resources/rest-api-spec/test/start_stop_scheduler.yaml index 6b307673e96..e3276bd8645 100644 --- a/elasticsearch/src/test/resources/rest-api-spec/test/start_stop_scheduler.yaml +++ b/elasticsearch/src/test/resources/rest-api-spec/test/start_stop_scheduler.yaml @@ -34,16 +34,16 @@ setup: "scheduler_id": "scheduler-1" "start": 0 - do: - xpack.prelert.get_jobs_stats: - job_id: "scheduled-job" - - match: { jobs.0.scheduler_status: STARTED } + xpack.prelert.get_schedulers_stats: + scheduler_id: "scheduler-1" + - match: { schedulers.0.status: STARTED } - do: xpack.prelert.stop_scheduler: "scheduler_id": "scheduler-1" - do: - xpack.prelert.get_jobs_stats: - job_id: "scheduled-job" - - match: { jobs.0.scheduler_status: STOPPED } + xpack.prelert.get_schedulers_stats: + scheduler_id: "scheduler-1" + - match: { schedulers.0.status: STOPPED } --- "Test start non existing scheduler": - do: