Skip to content

Commit c985f50

Browse files
author
David Roberts
authored
[ML] Add high level REST client docs for ML put job endpoint (#32843)
Relates #29827 Relates #32726
1 parent 0158b59 commit c985f50

File tree

5 files changed

+326
-18
lines changed

5 files changed

+326
-18
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
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.documentation;
20+
21+
import org.elasticsearch.action.ActionListener;
22+
import org.elasticsearch.action.LatchedActionListener;
23+
import org.elasticsearch.client.ESRestHighLevelClientTestCase;
24+
import org.elasticsearch.client.RequestOptions;
25+
import org.elasticsearch.client.RestHighLevelClient;
26+
import org.elasticsearch.common.unit.TimeValue;
27+
import org.elasticsearch.protocol.xpack.ml.PutJobRequest;
28+
import org.elasticsearch.protocol.xpack.ml.PutJobResponse;
29+
import org.elasticsearch.protocol.xpack.ml.job.config.AnalysisConfig;
30+
import org.elasticsearch.protocol.xpack.ml.job.config.DataDescription;
31+
import org.elasticsearch.protocol.xpack.ml.job.config.Detector;
32+
import org.elasticsearch.protocol.xpack.ml.job.config.Job;
33+
34+
import java.util.Collections;
35+
import java.util.Date;
36+
import java.util.List;
37+
import java.util.concurrent.CountDownLatch;
38+
import java.util.concurrent.TimeUnit;
39+
40+
import static org.hamcrest.Matchers.greaterThan;
41+
42+
public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
43+
44+
public void testCreateJob() throws Exception {
45+
RestHighLevelClient client = highLevelClient();
46+
47+
//tag::x-pack-ml-put-job-detector
48+
Detector.Builder detectorBuilder = new Detector.Builder()
49+
.setFunction("sum") // <1>
50+
.setFieldName("total") // <2>
51+
.setDetectorDescription("Sum of total"); // <3>
52+
//end::x-pack-ml-put-job-detector
53+
54+
//tag::x-pack-ml-put-job-analysis-config
55+
List<Detector> detectors = Collections.singletonList(detectorBuilder.build()); // <1>
56+
AnalysisConfig.Builder analysisConfigBuilder = new AnalysisConfig.Builder(detectors) // <2>
57+
.setBucketSpan(TimeValue.timeValueMinutes(10)); // <3>
58+
//end::x-pack-ml-put-job-analysis-config
59+
60+
//tag::x-pack-ml-put-job-data-description
61+
DataDescription.Builder dataDescriptionBuilder = new DataDescription.Builder()
62+
.setTimeField("timestamp"); // <1>
63+
//end::x-pack-ml-put-job-data-description
64+
65+
{
66+
String id = "job_1";
67+
68+
//tag::x-pack-ml-put-job-config
69+
Job.Builder jobBuilder = new Job.Builder(id) // <1>
70+
.setAnalysisConfig(analysisConfigBuilder) // <2>
71+
.setDataDescription(dataDescriptionBuilder) // <3>
72+
.setDescription("Total sum of requests"); // <4>
73+
//end::x-pack-ml-put-job-config
74+
75+
//tag::x-pack-ml-put-job-request
76+
PutJobRequest request = new PutJobRequest(jobBuilder.build()); // <1>
77+
//end::x-pack-ml-put-job-request
78+
79+
//tag::x-pack-ml-put-job-execute
80+
PutJobResponse response = client.machineLearning().putJob(request, RequestOptions.DEFAULT);
81+
//end::x-pack-ml-put-job-execute
82+
83+
//tag::x-pack-ml-put-job-response
84+
Date createTime = response.getResponse().getCreateTime(); // <1>
85+
//end::x-pack-ml-put-job-response
86+
assertThat(createTime.getTime(), greaterThan(0L));
87+
}
88+
{
89+
String id = "job_2";
90+
Job.Builder jobBuilder = new Job.Builder(id)
91+
.setAnalysisConfig(analysisConfigBuilder)
92+
.setDataDescription(dataDescriptionBuilder)
93+
.setDescription("Total sum of requests");
94+
95+
PutJobRequest request = new PutJobRequest(jobBuilder.build());
96+
// tag::x-pack-ml-put-job-execute-listener
97+
ActionListener<PutJobResponse> listener = new ActionListener<PutJobResponse>() {
98+
@Override
99+
public void onResponse(PutJobResponse response) {
100+
// <1>
101+
}
102+
103+
@Override
104+
public void onFailure(Exception e) {
105+
// <2>
106+
}
107+
};
108+
// end::x-pack-ml-put-job-execute-listener
109+
110+
// Replace the empty listener by a blocking listener in test
111+
final CountDownLatch latch = new CountDownLatch(1);
112+
listener = new LatchedActionListener<>(listener, latch);
113+
114+
// tag::x-pack-ml-put-job-execute-async
115+
client.machineLearning().putJobAsync(request, RequestOptions.DEFAULT, listener); // <1>
116+
// end::x-pack-ml-put-job-execute-async
117+
118+
assertTrue(latch.await(30L, TimeUnit.SECONDS));
119+
}
120+
}
121+
}
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
[[java-rest-high-x-pack-ml-put-job]]
2+
=== Put Job API
3+
4+
The Put Job API can be used to create a new {ml} job
5+
in the cluster. The API accepts a `PutJobRequest` object
6+
as a request and returns a `PutJobResponse`.
7+
8+
[[java-rest-high-x-pack-ml-put-job-request]]
9+
==== Put Job Request
10+
11+
A `PutJobRequest` requires the following argument:
12+
13+
["source","java",subs="attributes,callouts,macros"]
14+
--------------------------------------------------
15+
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-request]
16+
--------------------------------------------------
17+
<1> The configuration of the {ml} job to create as a `Job`
18+
19+
[[java-rest-high-x-pack-ml-put-job-config]]
20+
==== Job Configuration
21+
22+
The `Job` object contains all the details about the {ml} job
23+
configuration.
24+
25+
A `Job` requires the following arguments:
26+
27+
["source","java",subs="attributes,callouts,macros"]
28+
--------------------------------------------------
29+
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-config]
30+
--------------------------------------------------
31+
<1> The job ID
32+
<2> An analysis configuration
33+
<3> A data description
34+
<4> Optionally, a human-readable description
35+
36+
[[java-rest-high-x-pack-ml-put-job-analysis-config]]
37+
==== Analysis Configuration
38+
39+
The analysis configuration of the {ml} job is defined in the `AnalysisConfig`.
40+
`AnalysisConfig` reflects all the configuration
41+
settings that can be defined using the REST API.
42+
43+
Using the REST API, we could define this analysis configuration:
44+
45+
[source,js]
46+
--------------------------------------------------
47+
"analysis_config" : {
48+
"bucket_span" : "10m",
49+
"detectors" : [
50+
{
51+
"detector_description" : "Sum of total",
52+
"function" : "sum",
53+
"field_name" : "total"
54+
}
55+
]
56+
}
57+
--------------------------------------------------
58+
// NOTCONSOLE
59+
60+
Using the `AnalysisConfig` object and the high level REST client, the list
61+
of detectors must be built first.
62+
63+
An example of building a `Detector` instance is as follows:
64+
65+
["source","java",subs="attributes,callouts,macros"]
66+
--------------------------------------------------
67+
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-detector]
68+
--------------------------------------------------
69+
<1> The function to use
70+
<2> The field to apply the function to
71+
<3> Optionally, a human-readable description
72+
73+
Then the same configuration would be:
74+
75+
["source","java",subs="attributes,callouts,macros"]
76+
--------------------------------------------------
77+
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-analysis-config]
78+
--------------------------------------------------
79+
<1> Create a list of detectors
80+
<2> Pass the list of detectors to the analysis config builder constructor
81+
<3> The bucket span
82+
83+
[[java-rest-high-x-pack-ml-put-job-data-description]]
84+
==== Data Description
85+
86+
After defining the analysis config, the next thing to define is the
87+
data description, using a `DataDescription` instance. `DataDescription`
88+
reflects all the configuration settings that can be defined using the
89+
REST API.
90+
91+
Using the REST API, we could define this metrics configuration:
92+
93+
[source,js]
94+
--------------------------------------------------
95+
"data_description" : {
96+
"time_field" : "timestamp"
97+
}
98+
--------------------------------------------------
99+
// NOTCONSOLE
100+
101+
Using the `DataDescription` object and the high level REST client, the same
102+
configuration would be:
103+
104+
["source","java",subs="attributes,callouts,macros"]
105+
--------------------------------------------------
106+
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-data-description]
107+
--------------------------------------------------
108+
<1> The time field
109+
110+
[[java-rest-high-x-pack-ml-put-job-execution]]
111+
==== Execution
112+
113+
The Put Job API can be executed through a `MachineLearningClient`
114+
instance. Such an instance can be retrieved from a `RestHighLevelClient`
115+
using the `machineLearning()` method:
116+
117+
["source","java",subs="attributes,callouts,macros"]
118+
--------------------------------------------------
119+
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-execute]
120+
--------------------------------------------------
121+
122+
[[java-rest-high-x-pack-ml-put-job-response]]
123+
==== Response
124+
125+
The returned `PutJobResponse` returns the full representation of
126+
the new {ml} job if it has been successfully created. This will
127+
contain the creation time and other fields initialized using
128+
default values:
129+
130+
["source","java",subs="attributes,callouts,macros"]
131+
--------------------------------------------------
132+
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-response]
133+
--------------------------------------------------
134+
<1> The creation time is a field that was not passed in the `Job` object in the request
135+
136+
[[java-rest-high-x-pack-ml-put-job-async]]
137+
==== Asynchronous Execution
138+
139+
This request can be executed asynchronously:
140+
141+
["source","java",subs="attributes,callouts,macros"]
142+
--------------------------------------------------
143+
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-execute-async]
144+
--------------------------------------------------
145+
<1> The `PutMlJobRequest` to execute and the `ActionListener` to use when
146+
the execution completes
147+
148+
The asynchronous method does not block and returns immediately. Once it is
149+
completed the `ActionListener` is called back using the `onResponse` method
150+
if the execution successfully completed or using the `onFailure` method if
151+
it failed.
152+
153+
A typical listener for `PutJobResponse` looks like:
154+
155+
["source","java",subs="attributes,callouts,macros"]
156+
--------------------------------------------------
157+
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-execute-listener]
158+
--------------------------------------------------
159+
<1> Called when the execution is successfully completed. The response is
160+
provided as an argument
161+
<2> Called in case of failure. The raised exception is provided as an argument

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,14 @@ include::licensing/put-license.asciidoc[]
200200
include::licensing/get-license.asciidoc[]
201201
include::licensing/delete-license.asciidoc[]
202202

203+
== Machine Learning APIs
204+
205+
The Java High Level REST Client supports the following Machine Learning APIs:
206+
207+
* <<java-rest-high-x-pack-ml-put-job>>
208+
209+
include::ml/put_job.asciidoc[]
210+
203211
== Migration APIs
204212

205213
The Java High Level REST Client supports the following Migration APIs:

x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/ml/job/config/AnalysisConfig.java

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ public Builder(AnalysisConfig analysisConfig) {
333333
this.multivariateByFields = analysisConfig.multivariateByFields;
334334
}
335335

336-
public void setDetectors(List<Detector> detectors) {
336+
public Builder setDetectors(List<Detector> detectors) {
337337
Objects.requireNonNull(detectors, "[" + DETECTORS.getPreferredName() + "] must not be null");
338338
// We always assign sequential IDs to the detectors that are correct for this analysis config
339339
int detectorIndex = 0;
@@ -344,50 +344,62 @@ public void setDetectors(List<Detector> detectors) {
344344
sequentialIndexDetectors.add(builder.build());
345345
}
346346
this.detectors = sequentialIndexDetectors;
347+
return this;
347348
}
348349

349-
public void setDetector(int detectorIndex, Detector detector) {
350+
public Builder setDetector(int detectorIndex, Detector detector) {
350351
detectors.set(detectorIndex, detector);
352+
return this;
351353
}
352354

353-
public void setBucketSpan(TimeValue bucketSpan) {
355+
public Builder setBucketSpan(TimeValue bucketSpan) {
354356
this.bucketSpan = bucketSpan;
357+
return this;
355358
}
356359

357-
public void setLatency(TimeValue latency) {
360+
public Builder setLatency(TimeValue latency) {
358361
this.latency = latency;
362+
return this;
359363
}
360364

361-
public void setCategorizationFieldName(String categorizationFieldName) {
365+
public Builder setCategorizationFieldName(String categorizationFieldName) {
362366
this.categorizationFieldName = categorizationFieldName;
367+
return this;
363368
}
364369

365-
public void setCategorizationFilters(List<String> categorizationFilters) {
370+
public Builder setCategorizationFilters(List<String> categorizationFilters) {
366371
this.categorizationFilters = categorizationFilters;
372+
return this;
367373
}
368374

369-
public void setCategorizationAnalyzerConfig(CategorizationAnalyzerConfig categorizationAnalyzerConfig) {
375+
public Builder setCategorizationAnalyzerConfig(CategorizationAnalyzerConfig categorizationAnalyzerConfig) {
370376
this.categorizationAnalyzerConfig = categorizationAnalyzerConfig;
377+
return this;
371378
}
372379

373-
public void setSummaryCountFieldName(String summaryCountFieldName) {
380+
public Builder setSummaryCountFieldName(String summaryCountFieldName) {
374381
this.summaryCountFieldName = summaryCountFieldName;
382+
return this;
375383
}
376384

377-
public void setInfluencers(List<String> influencers) {
385+
public Builder setInfluencers(List<String> influencers) {
378386
this.influencers = Objects.requireNonNull(influencers, INFLUENCERS.getPreferredName());
387+
return this;
379388
}
380389

381-
public void setOverlappingBuckets(Boolean overlappingBuckets) {
390+
public Builder setOverlappingBuckets(Boolean overlappingBuckets) {
382391
this.overlappingBuckets = overlappingBuckets;
392+
return this;
383393
}
384394

385-
public void setResultFinalizationWindow(Long resultFinalizationWindow) {
395+
public Builder setResultFinalizationWindow(Long resultFinalizationWindow) {
386396
this.resultFinalizationWindow = resultFinalizationWindow;
397+
return this;
387398
}
388399

389-
public void setMultivariateByFields(Boolean multivariateByFields) {
400+
public Builder setMultivariateByFields(Boolean multivariateByFields) {
390401
this.multivariateByFields = multivariateByFields;
402+
return this;
391403
}
392404

393405
public AnalysisConfig build() {

0 commit comments

Comments
 (0)