瀏覽代碼

[ML] Add high level REST client docs for ML put job endpoint (#32843)

Relates #29827
Relates #32726
David Roberts 7 年之前
父節點
當前提交
c985f500f4

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

@@ -0,0 +1,121 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.elasticsearch.client.documentation;
+
+import org.elasticsearch.action.ActionListener;
+import org.elasticsearch.action.LatchedActionListener;
+import org.elasticsearch.client.ESRestHighLevelClientTestCase;
+import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.client.RestHighLevelClient;
+import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.protocol.xpack.ml.PutJobRequest;
+import org.elasticsearch.protocol.xpack.ml.PutJobResponse;
+import org.elasticsearch.protocol.xpack.ml.job.config.AnalysisConfig;
+import org.elasticsearch.protocol.xpack.ml.job.config.DataDescription;
+import org.elasticsearch.protocol.xpack.ml.job.config.Detector;
+import org.elasticsearch.protocol.xpack.ml.job.config.Job;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import static org.hamcrest.Matchers.greaterThan;
+
+public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
+
+    public void testCreateJob() throws Exception {
+        RestHighLevelClient client = highLevelClient();
+
+        //tag::x-pack-ml-put-job-detector
+        Detector.Builder detectorBuilder = new Detector.Builder()
+            .setFunction("sum")                                    // <1>
+            .setFieldName("total")                                 // <2>
+            .setDetectorDescription("Sum of total");               // <3>
+        //end::x-pack-ml-put-job-detector
+
+        //tag::x-pack-ml-put-job-analysis-config
+        List<Detector> detectors = Collections.singletonList(detectorBuilder.build());       // <1>
+        AnalysisConfig.Builder analysisConfigBuilder = new AnalysisConfig.Builder(detectors) // <2>
+            .setBucketSpan(TimeValue.timeValueMinutes(10));                                  // <3>
+        //end::x-pack-ml-put-job-analysis-config
+
+        //tag::x-pack-ml-put-job-data-description
+        DataDescription.Builder dataDescriptionBuilder = new DataDescription.Builder()
+            .setTimeField("timestamp");  // <1>
+        //end::x-pack-ml-put-job-data-description
+
+        {
+            String id = "job_1";
+
+            //tag::x-pack-ml-put-job-config
+            Job.Builder jobBuilder = new Job.Builder(id)      // <1>
+                .setAnalysisConfig(analysisConfigBuilder)     // <2>
+                .setDataDescription(dataDescriptionBuilder)   // <3>
+                .setDescription("Total sum of requests");     // <4>
+            //end::x-pack-ml-put-job-config
+
+            //tag::x-pack-ml-put-job-request
+            PutJobRequest request = new PutJobRequest(jobBuilder.build()); // <1>
+            //end::x-pack-ml-put-job-request
+
+            //tag::x-pack-ml-put-job-execute
+            PutJobResponse response = client.machineLearning().putJob(request, RequestOptions.DEFAULT);
+            //end::x-pack-ml-put-job-execute
+
+            //tag::x-pack-ml-put-job-response
+            Date createTime = response.getResponse().getCreateTime(); // <1>
+            //end::x-pack-ml-put-job-response
+            assertThat(createTime.getTime(), greaterThan(0L));
+        }
+        {
+            String id = "job_2";
+            Job.Builder jobBuilder = new Job.Builder(id)
+                .setAnalysisConfig(analysisConfigBuilder)
+                .setDataDescription(dataDescriptionBuilder)
+                .setDescription("Total sum of requests");
+
+            PutJobRequest request = new PutJobRequest(jobBuilder.build());
+            // tag::x-pack-ml-put-job-execute-listener
+            ActionListener<PutJobResponse> listener = new ActionListener<PutJobResponse>() {
+                @Override
+                public void onResponse(PutJobResponse response) {
+                    // <1>
+                }
+
+                @Override
+                public void onFailure(Exception e) {
+                    // <2>
+                }
+            };
+            // end::x-pack-ml-put-job-execute-listener
+
+            // Replace the empty listener by a blocking listener in test
+            final CountDownLatch latch = new CountDownLatch(1);
+            listener = new LatchedActionListener<>(listener, latch);
+
+            // tag::x-pack-ml-put-job-execute-async
+            client.machineLearning().putJobAsync(request, RequestOptions.DEFAULT, listener); // <1>
+            // end::x-pack-ml-put-job-execute-async
+
+            assertTrue(latch.await(30L, TimeUnit.SECONDS));
+        }
+    }
+}

+ 161 - 0
docs/java-rest/high-level/ml/put_job.asciidoc

@@ -0,0 +1,161 @@
+[[java-rest-high-x-pack-ml-put-job]]
+=== Put Job API
+
+The Put Job API can be used to create a new {ml} job
+in the cluster. The API accepts a `PutJobRequest` object
+as a request and returns a `PutJobResponse`.
+
+[[java-rest-high-x-pack-ml-put-job-request]]
+==== Put Job Request
+
+A `PutJobRequest` requires the following argument:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-request]
+--------------------------------------------------
+<1> The configuration of the {ml} job to create as a `Job`
+
+[[java-rest-high-x-pack-ml-put-job-config]]
+==== Job Configuration
+
+The `Job` object contains all the details about the {ml} job
+configuration.
+
+A `Job` requires the following arguments:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-config]
+--------------------------------------------------
+<1> The job ID
+<2> An analysis configuration
+<3> A data description
+<4> Optionally, a human-readable description
+
+[[java-rest-high-x-pack-ml-put-job-analysis-config]]
+==== Analysis Configuration
+
+The analysis configuration of the {ml} job is defined in the `AnalysisConfig`.
+`AnalysisConfig` reflects all the configuration
+settings that can be defined using the REST API.
+
+Using the REST API, we could define this analysis configuration:
+
+[source,js]
+--------------------------------------------------
+"analysis_config" : {
+  "bucket_span" : "10m",
+  "detectors" : [
+    {
+      "detector_description" : "Sum of total",
+      "function" : "sum",
+      "field_name" : "total"
+    }
+  ]
+}
+--------------------------------------------------
+// NOTCONSOLE
+
+Using the `AnalysisConfig` object and the high level REST client, the list
+of detectors must be built first.
+
+An example of building a `Detector` instance is as follows:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-detector]
+--------------------------------------------------
+<1> The function to use
+<2> The field to apply the function to
+<3> Optionally, a human-readable description
+
+Then the same configuration would be:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-analysis-config]
+--------------------------------------------------
+<1> Create a list of detectors
+<2> Pass the list of detectors to the analysis config builder constructor
+<3> The bucket span
+
+[[java-rest-high-x-pack-ml-put-job-data-description]]
+==== Data Description
+
+After defining the analysis config, the next thing to define is the
+data description, using a `DataDescription` instance. `DataDescription`
+reflects all the configuration settings that can be defined using the
+REST API.
+
+Using the REST API, we could define this metrics configuration:
+
+[source,js]
+--------------------------------------------------
+"data_description" : {
+  "time_field" : "timestamp"
+}
+--------------------------------------------------
+// NOTCONSOLE
+
+Using the `DataDescription` object and the high level REST client, the same
+configuration would be:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-data-description]
+--------------------------------------------------
+<1> The time field
+
+[[java-rest-high-x-pack-ml-put-job-execution]]
+==== Execution
+
+The Put Job API can be executed through a `MachineLearningClient`
+instance. Such an instance can be retrieved from a `RestHighLevelClient`
+using the `machineLearning()` method:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-execute]
+--------------------------------------------------
+
+[[java-rest-high-x-pack-ml-put-job-response]]
+==== Response
+
+The returned `PutJobResponse` returns the full representation of
+the new {ml} job if it has been successfully created. This will
+contain the creation time and other fields initialized using
+default values:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-response]
+--------------------------------------------------
+<1> The creation time is a field that was not passed in the `Job` object in the request
+
+[[java-rest-high-x-pack-ml-put-job-async]]
+==== Asynchronous Execution
+
+This request can be executed asynchronously:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-execute-async]
+--------------------------------------------------
+<1> The `PutMlJobRequest` to execute and the `ActionListener` to use when
+the execution completes
+
+The asynchronous method does not block and returns immediately. Once it is
+completed the `ActionListener` is called back using the `onResponse` method
+if the execution successfully completed or using the `onFailure` method if
+it failed.
+
+A typical listener for `PutJobResponse` looks like:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-put-job-execute-listener]
+--------------------------------------------------
+<1> Called when the execution is successfully completed. The response is
+provided as an argument
+<2> Called in case of failure. The raised exception is provided as an argument

+ 8 - 0
docs/java-rest/high-level/supported-apis.asciidoc

@@ -200,6 +200,14 @@ include::licensing/put-license.asciidoc[]
 include::licensing/get-license.asciidoc[]
 include::licensing/delete-license.asciidoc[]
 
+== Machine Learning APIs
+
+The Java High Level REST Client supports the following Machine Learning APIs:
+
+* <<java-rest-high-x-pack-ml-put-job>>
+
+include::ml/put_job.asciidoc[]
+
 == Migration APIs
 
 The Java High Level REST Client supports the following Migration APIs:

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

@@ -333,7 +333,7 @@ public class AnalysisConfig implements ToXContentObject {
             this.multivariateByFields = analysisConfig.multivariateByFields;
         }
 
-        public void setDetectors(List<Detector> detectors) {
+        public Builder setDetectors(List<Detector> detectors) {
             Objects.requireNonNull(detectors,  "[" + DETECTORS.getPreferredName() + "] must not be null");
             // We always assign sequential IDs to the detectors that are correct for this analysis config
             int detectorIndex = 0;
@@ -344,50 +344,62 @@ public class AnalysisConfig implements ToXContentObject {
                 sequentialIndexDetectors.add(builder.build());
             }
             this.detectors = sequentialIndexDetectors;
+            return this;
         }
 
-        public void setDetector(int detectorIndex, Detector detector) {
+        public Builder setDetector(int detectorIndex, Detector detector) {
             detectors.set(detectorIndex, detector);
+            return this;
         }
 
-        public void setBucketSpan(TimeValue bucketSpan) {
+        public Builder setBucketSpan(TimeValue bucketSpan) {
             this.bucketSpan = bucketSpan;
+            return this;
         }
 
-        public void setLatency(TimeValue latency) {
+        public Builder setLatency(TimeValue latency) {
             this.latency = latency;
+            return this;
         }
 
-        public void setCategorizationFieldName(String categorizationFieldName) {
+        public Builder setCategorizationFieldName(String categorizationFieldName) {
             this.categorizationFieldName = categorizationFieldName;
+            return this;
         }
 
-        public void setCategorizationFilters(List<String> categorizationFilters) {
+        public Builder setCategorizationFilters(List<String> categorizationFilters) {
             this.categorizationFilters = categorizationFilters;
+            return this;
         }
 
-        public void setCategorizationAnalyzerConfig(CategorizationAnalyzerConfig categorizationAnalyzerConfig) {
+        public Builder setCategorizationAnalyzerConfig(CategorizationAnalyzerConfig categorizationAnalyzerConfig) {
             this.categorizationAnalyzerConfig = categorizationAnalyzerConfig;
+            return this;
         }
 
-        public void setSummaryCountFieldName(String summaryCountFieldName) {
+        public Builder setSummaryCountFieldName(String summaryCountFieldName) {
             this.summaryCountFieldName = summaryCountFieldName;
+            return this;
         }
 
-        public void setInfluencers(List<String> influencers) {
+        public Builder setInfluencers(List<String> influencers) {
             this.influencers = Objects.requireNonNull(influencers, INFLUENCERS.getPreferredName());
+            return this;
         }
 
-        public void setOverlappingBuckets(Boolean overlappingBuckets) {
+        public Builder setOverlappingBuckets(Boolean overlappingBuckets) {
             this.overlappingBuckets = overlappingBuckets;
+            return this;
         }
 
-        public void setResultFinalizationWindow(Long resultFinalizationWindow) {
+        public Builder setResultFinalizationWindow(Long resultFinalizationWindow) {
             this.resultFinalizationWindow = resultFinalizationWindow;
+            return this;
         }
 
-        public void setMultivariateByFields(Boolean multivariateByFields) {
+        public Builder setMultivariateByFields(Boolean multivariateByFields) {
             this.multivariateByFields = multivariateByFields;
+            return this;
         }
 
         public AnalysisConfig build() {

+ 12 - 6
x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/ml/job/config/DataDescription.java

@@ -243,28 +243,34 @@ public class DataDescription implements ToXContentObject {
         private Character fieldDelimiter;
         private Character quoteCharacter;
 
-        public void setFormat(DataFormat format) {
+        public Builder setFormat(DataFormat format) {
             dataFormat = Objects.requireNonNull(format);
+            return this;
         }
 
-        private void setFormat(String format) {
+        private Builder setFormat(String format) {
             setFormat(DataFormat.forString(format));
+            return this;
         }
 
-        public void setTimeField(String fieldName) {
+        public Builder setTimeField(String fieldName) {
             timeFieldName = Objects.requireNonNull(fieldName);
+            return this;
         }
 
-        public void setTimeFormat(String format) {
+        public Builder setTimeFormat(String format) {
             timeFormat = Objects.requireNonNull(format);
+            return this;
         }
 
-        public void setFieldDelimiter(Character delimiter) {
+        public Builder setFieldDelimiter(Character delimiter) {
             fieldDelimiter = delimiter;
+            return this;
         }
 
-        public void setQuoteCharacter(Character value) {
+        public Builder setQuoteCharacter(Character value) {
             quoteCharacter = value;
+            return this;
         }
 
         public DataDescription build() {