Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions docs/reference/ml/anomaly-detection/apis/delete-forecast.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<titleabbrev>Delete forecast</titleabbrev>
++++

Deletes forecasts from a {ml} job.
Deletes forecasts from a {ml} job.

[[ml-delete-forecast-request]]
== {api-request-title}
Expand All @@ -27,12 +27,12 @@ Deletes forecasts from a {ml} job.
[[ml-delete-forecast-desc]]
== {api-description-title}

By default, forecasts are retained for 14 days. You can specify a different
By default, forecasts are retained for 14 days. You can specify a different
retention period with the `expires_in` parameter in the
<<ml-forecast,forecast jobs API>>. The delete forecast API enables you to delete
one or more forecasts before they expire.

NOTE: When you delete a job, its associated forecasts are deleted.
NOTE: When you delete a job, its associated forecasts are deleted.

For more information, see
{ml-docs}/ml-overview.html#ml-forecasting[Forecasting the future].
Expand All @@ -42,26 +42,26 @@ For more information, see

`<forecast_id>`::
(Optional, string) A comma-separated list of forecast identifiers. If you do not
specify this optional parameter or if you specify `_all`, the API deletes all
forecasts from the job.
specify this optional parameter or if you specify `_all` or `*` the API deletes all
forecasts from the job.

`<job_id>`::
(Required, string)
include::{es-repo-dir}/ml/ml-shared.asciidoc[tag=job-id-anomaly-detection]


[[ml-delete-forecast-query-parms]]
== {api-query-parms-title}

`allow_no_forecasts`::
(Optional, boolean) Specifies whether an error occurs when there are no
forecasts. In particular, if this parameter is set to `false` and there are no
forecasts. In particular, if this parameter is set to `false` and there are no
forecasts associated with the job, attempts to delete all forecasts return an
error. The default value is `true`.

`timeout`::
(Optional, <<time-units, time units>>) Specifies the period of time to wait
for the completion of the delete operation. When this period of time elapses,
(Optional, <<time-units, time units>>) Specifies the period of time to wait
for the completion of the delete operation. When this period of time elapses,
the API fails and returns an error. The default value is `30s`.

[[ml-delete-forecast-example]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ Retrieves information about the scheduled events in calendars.
[[ml-get-calendar-event-desc]]
== {api-description-title}

You can get scheduled event information for a single calendar or for all
calendars by using `_all`.
You can get scheduled event information for multiple calendars in a single
API request by using a comma-separated list of ids or a wildcard expression.
You can get scheduled event information for all calendars by using `_all`,
by specifying `*` as the `<calendar_id>`, or by omitting the `<calendar_id>`.

For more information, see
{ml-docs}/ml-calendars.html[Calendars and scheduled events].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ Retrieves configuration information for calendars.
[[ml-get-calendar-desc]]
== {api-description-title}

You can get information for a single calendar or for all calendars by using
`_all`.
You can get information for multiple calendars in a single API request by using a
comma-separated list of ids or a wildcard expression. You can get
information for all calendars by using `_all`, by specifying `*` as the
`<calendar_id>`, or by omitting the `<calendar_id>`.

For more information, see
For more information, see
{ml-docs}/ml-calendars.html[Calendars and scheduled events].

[[ml-get-calendar-path-parms]]
Expand Down
10 changes: 6 additions & 4 deletions docs/reference/ml/anomaly-detection/apis/get-snapshot.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ include::{es-repo-dir}/ml/ml-shared.asciidoc[tag=job-id-anomaly-detection]
include::{es-repo-dir}/ml/ml-shared.asciidoc[tag=snapshot-id]
+
--
If you do not specify this optional parameter, the API returns information about
all model snapshots.
You can multiple snapshots for a single job in a single API request
by using a comma-separated list of `<snapshot_id>` or a wildcard expression.
You can get all snapshots for all calendars by using `_all`,
by specifying `*` as the `<snapshot_id>`, or by omitting the `<snapshot_id>`.
--

[[ml-get-snapshot-request-body]]
Expand Down Expand Up @@ -64,7 +66,7 @@ all model snapshots.
[[ml-get-snapshot-results]]
== {api-response-body-title}

The API returns an array of model snapshot objects, which have the following
The API returns an array of model snapshot objects, which have the following
properties:

`description`::
Expand All @@ -73,7 +75,7 @@ properties:
`job_id`::
(string) A numerical character string that uniquely identifies the job that
the snapshot was created for.

`latest_record_time_stamp`::
(date) The timestamp of the latest processed record.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public ActionRequestValidationException validate() {

if (jobId != null && Strings.isAllOrWildcard(calendarId) == false) {
e = ValidateActions.addValidationError("If " + Job.ID.getPreferredName() + " is used " +
Calendar.ID.getPreferredName() + " must be '" + GetCalendarsAction.Request.ALL + "'", e);
Calendar.ID.getPreferredName() + " must be '" + GetCalendarsAction.Request.ALL + "' or '*'", e);
}
return e;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void testValidate() {

ActionRequestValidationException validationException = request.validate();
assertNotNull(validationException);
assertEquals("Validation Failed: 1: If job_id is used calendar_id must be '_all';", validationException.getMessage());
assertEquals("Validation Failed: 1: If job_id is used calendar_id must be '_all' or '*';", validationException.getMessage());

request = new GetCalendarEventsAction.Request("_all");
request.setJobId("foo");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ public void testNoData() {
equalTo("Cannot run forecast: Forecast cannot be executed as job requires data to have been processed and modeled"));
}

public void testMemoryStatus() throws Exception {
public void testMemoryStatus() {
Detector.Builder detector = new Detector.Builder("mean", "value");
detector.setByFieldName("clientIP");

Expand Down Expand Up @@ -287,6 +287,74 @@ public void testOverflowToDisk() throws Exception {

}

public void testDeleteWildCard() throws Exception {
Detector.Builder detector = new Detector.Builder("mean", "value");

TimeValue bucketSpan = TimeValue.timeValueHours(1);
AnalysisConfig.Builder analysisConfig = new AnalysisConfig.Builder(Collections.singletonList(detector.build()));
analysisConfig.setBucketSpan(bucketSpan);
DataDescription.Builder dataDescription = new DataDescription.Builder();
dataDescription.setTimeFormat("epoch");

Job.Builder job = new Job.Builder("forecast-it-test-delete-wildcard");
job.setAnalysisConfig(analysisConfig);
job.setDataDescription(dataDescription);

registerJob(job);
putJob(job);
openJob(job.getId());

long now = Instant.now().getEpochSecond();
long timestamp = now - 50 * bucketSpan.seconds();
List<String> data = new ArrayList<>();
while (timestamp < now) {
data.add(createJsonRecord(createRecord(timestamp, 10.0)));
data.add(createJsonRecord(createRecord(timestamp, 30.0)));
timestamp += bucketSpan.seconds();
}

postData(job.getId(), data.stream().collect(Collectors.joining()));
flushJob(job.getId(), false);
String forecastIdDefaultDurationDefaultExpiry = forecast(job.getId(), null, null);
String forecastIdDuration1HourNoExpiry = forecast(job.getId(), TimeValue.timeValueHours(1), TimeValue.ZERO);
String forecastId2Duration1HourNoExpiry = forecast(job.getId(), TimeValue.timeValueHours(1), TimeValue.ZERO);
String forecastId2Duration1HourNoExpiry2 = forecast(job.getId(), TimeValue.timeValueHours(1), TimeValue.ZERO);
waitForecastToFinish(job.getId(), forecastIdDefaultDurationDefaultExpiry);
waitForecastToFinish(job.getId(), forecastIdDuration1HourNoExpiry);
waitForecastToFinish(job.getId(), forecastId2Duration1HourNoExpiry);
waitForecastToFinish(job.getId(), forecastId2Duration1HourNoExpiry2);
closeJob(job.getId());

assertNotNull(getForecastStats(job.getId(), forecastIdDefaultDurationDefaultExpiry));
assertNotNull(getForecastStats(job.getId(), forecastIdDuration1HourNoExpiry));
assertNotNull(getForecastStats(job.getId(), forecastId2Duration1HourNoExpiry));
assertNotNull(getForecastStats(job.getId(), forecastId2Duration1HourNoExpiry2));

{
DeleteForecastAction.Request request = new DeleteForecastAction.Request(job.getId(),
forecastIdDefaultDurationDefaultExpiry.substring(0, forecastIdDefaultDurationDefaultExpiry.length() - 2) + "*"
+ ","
+ forecastIdDuration1HourNoExpiry);
AcknowledgedResponse response = client().execute(DeleteForecastAction.INSTANCE, request).actionGet();
assertTrue(response.isAcknowledged());

assertNull(getForecastStats(job.getId(), forecastIdDefaultDurationDefaultExpiry));
assertNull(getForecastStats(job.getId(), forecastIdDuration1HourNoExpiry));
assertNotNull(getForecastStats(job.getId(), forecastId2Duration1HourNoExpiry));
assertNotNull(getForecastStats(job.getId(), forecastId2Duration1HourNoExpiry2));
}

{
DeleteForecastAction.Request request = new DeleteForecastAction.Request(job.getId(), "*");
AcknowledgedResponse response = client().execute(DeleteForecastAction.INSTANCE, request).actionGet();
assertTrue(response.isAcknowledged());

assertNull(getForecastStats(job.getId(), forecastId2Duration1HourNoExpiry));
assertNull(getForecastStats(job.getId(), forecastId2Duration1HourNoExpiry2));
}

}

public void testDelete() throws Exception {
Detector.Builder detector = new Detector.Builder("mean", "value");

Expand Down Expand Up @@ -317,6 +385,8 @@ public void testDelete() throws Exception {
flushJob(job.getId(), false);
String forecastIdDefaultDurationDefaultExpiry = forecast(job.getId(), null, null);
String forecastIdDuration1HourNoExpiry = forecast(job.getId(), TimeValue.timeValueHours(1), TimeValue.ZERO);
String forecastId2Duration1HourNoExpiry = forecast(job.getId(), TimeValue.timeValueHours(1), TimeValue.ZERO);
String forecastId2Duration1HourNoExpiry2 = forecast(job.getId(), TimeValue.timeValueHours(1), TimeValue.ZERO);
waitForecastToFinish(job.getId(), forecastIdDefaultDurationDefaultExpiry);
waitForecastToFinish(job.getId(), forecastIdDuration1HourNoExpiry);
closeJob(job.getId());
Expand All @@ -333,13 +403,11 @@ public void testDelete() throws Exception {
forecastIdDefaultDurationDefaultExpiry + "," + forecastIdDuration1HourNoExpiry);
AcknowledgedResponse response = client().execute(DeleteForecastAction.INSTANCE, request).actionGet();
assertTrue(response.isAcknowledged());
}

{
ForecastRequestStats forecastStats = getForecastStats(job.getId(), forecastIdDefaultDurationDefaultExpiry);
assertNull(forecastStats);
ForecastRequestStats otherStats = getForecastStats(job.getId(), forecastIdDuration1HourNoExpiry);
assertNull(otherStats);
assertNull(getForecastStats(job.getId(), forecastIdDefaultDurationDefaultExpiry));
assertNull(getForecastStats(job.getId(), forecastIdDuration1HourNoExpiry));
assertNotNull(getForecastStats(job.getId(), forecastId2Duration1HourNoExpiry));
assertNotNull(getForecastStats(job.getId(), forecastId2Duration1HourNoExpiry2));
}

{
Expand All @@ -354,6 +422,9 @@ public void testDelete() throws Exception {
DeleteForecastAction.Request request = new DeleteForecastAction.Request(job.getId(), Metadata.ALL);
AcknowledgedResponse response = client().execute(DeleteForecastAction.INSTANCE, request).actionGet();
assertTrue(response.isAcknowledged());

assertNull(getForecastStats(job.getId(), forecastId2Duration1HourNoExpiry));
assertNull(getForecastStats(job.getId(), forecastId2Duration1HourNoExpiry2));
}

{
Expand Down
Loading