diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/MLRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/MLRequestConverters.java
index f3844566f6e05..8e11151667bc5 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/MLRequestConverters.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/MLRequestConverters.java
@@ -53,6 +53,7 @@
import org.elasticsearch.client.ml.GetModelSnapshotsRequest;
import org.elasticsearch.client.ml.GetOverallBucketsRequest;
import org.elasticsearch.client.ml.GetRecordsRequest;
+import org.elasticsearch.client.ml.MlInfoRequest;
import org.elasticsearch.client.ml.OpenJobRequest;
import org.elasticsearch.client.ml.PostCalendarEventRequest;
import org.elasticsearch.client.ml.PostDataRequest;
@@ -663,6 +664,13 @@ static Request deleteFilter(DeleteFilterRequest deleteFilterRequest) {
return request;
}
+ static Request mlInfo(MlInfoRequest infoRequest) {
+ String endpoint = new EndpointBuilder()
+ .addPathPartAsIs("_xpack", "ml", "info")
+ .build();
+ return new Request(HttpGet.METHOD_NAME, endpoint);
+ }
+
static Request findFileStructure(FindFileStructureRequest findFileStructureRequest) {
String endpoint = new EndpointBuilder()
.addPathPartAsIs("_xpack")
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/MachineLearningClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/MachineLearningClient.java
index fa204c5bccedd..aaff35a238998 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/MachineLearningClient.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/MachineLearningClient.java
@@ -65,6 +65,8 @@
import org.elasticsearch.client.ml.GetOverallBucketsResponse;
import org.elasticsearch.client.ml.GetRecordsRequest;
import org.elasticsearch.client.ml.GetRecordsResponse;
+import org.elasticsearch.client.ml.MlInfoRequest;
+import org.elasticsearch.client.ml.MlInfoResponse;
import org.elasticsearch.client.ml.OpenJobRequest;
import org.elasticsearch.client.ml.OpenJobResponse;
import org.elasticsearch.client.ml.PostCalendarEventRequest;
@@ -1758,6 +1760,44 @@ public void deleteFilterAsync(DeleteFilterRequest request, RequestOptions option
Collections.emptySet());
}
+ /**
+ * Gets Machine Learning information about default values and limits.
+ *
+ * For additional info
+ * see Machine Learning info
+ *
+ * @param request The request of Machine Learning info
+ * @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
+ * @return response info about default values and limits
+ * @throws IOException when there is a serialization issue sending the request or receiving the response
+ */
+ public MlInfoResponse getMlInfo(MlInfoRequest request, RequestOptions options) throws IOException {
+ return restHighLevelClient.performRequestAndParseEntity(request,
+ MLRequestConverters::mlInfo,
+ options,
+ MlInfoResponse::fromXContent,
+ Collections.emptySet());
+ }
+
+ /**
+ * Gets Machine Learning information about default values and limits, asynchronously.
+ *
+ * For additional info
+ * see Machine Learning info
+ *
+ * @param request The request of Machine Learning info
+ * @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
+ * @param listener Listener to be notified upon request completion
+ */
+ public void getMlInfoAsync(MlInfoRequest request, RequestOptions options, ActionListener listener) {
+ restHighLevelClient.performRequestAsyncAndParseEntity(request,
+ MLRequestConverters::mlInfo,
+ options,
+ MlInfoResponse::fromXContent,
+ listener,
+ Collections.emptySet());
+ }
+
/**
* Finds the structure of a file
*
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/MlInfoRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/MlInfoRequest.java
new file mode 100644
index 0000000000000..19b6e7799c804
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/MlInfoRequest.java
@@ -0,0 +1,25 @@
+/*
+ * 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.ml;
+
+import org.elasticsearch.client.Validatable;
+
+public class MlInfoRequest implements Validatable {
+}
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/MlInfoResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/MlInfoResponse.java
new file mode 100644
index 0000000000000..41f21efbe3d65
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/MlInfoResponse.java
@@ -0,0 +1,61 @@
+/*
+ * 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.ml;
+
+import org.elasticsearch.client.Validatable;
+import org.elasticsearch.common.xcontent.XContentParser;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Objects;
+
+public class MlInfoResponse implements Validatable {
+ private final Map info;
+
+ private MlInfoResponse(Map info) {
+ this.info = info;
+ }
+
+ public Map getInfo() {
+ return info;
+ }
+
+ public static MlInfoResponse fromXContent(XContentParser parser) throws IOException {
+ Map info = parser.map();
+ return new MlInfoResponse(info);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(info);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ MlInfoResponse other = (MlInfoResponse) obj;
+ return Objects.equals(info, other.info);
+ }
+}
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/MLRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/MLRequestConvertersTests.java
index 107f4614505b2..98cd3761e5a3c 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/MLRequestConvertersTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/MLRequestConvertersTests.java
@@ -50,6 +50,7 @@
import org.elasticsearch.client.ml.GetModelSnapshotsRequest;
import org.elasticsearch.client.ml.GetOverallBucketsRequest;
import org.elasticsearch.client.ml.GetRecordsRequest;
+import org.elasticsearch.client.ml.MlInfoRequest;
import org.elasticsearch.client.ml.OpenJobRequest;
import org.elasticsearch.client.ml.PostCalendarEventRequest;
import org.elasticsearch.client.ml.PostDataRequest;
@@ -728,6 +729,16 @@ public void testDeleteFilter() {
assertNull(request.getEntity());
}
+ public void testMlInfo() {
+ MlInfoRequest infoRequest = new MlInfoRequest();
+
+ Request request = MLRequestConverters.mlInfo(infoRequest);
+
+ assertEquals(HttpGet.METHOD_NAME, request.getMethod());
+ assertThat(request.getEndpoint(), equalTo("/_xpack/ml/info"));
+ assertNull(request.getEntity());
+ }
+
public void testFindFileStructure() throws Exception {
String sample = randomAlphaOfLength(randomIntBetween(1000, 2000));
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/MachineLearningIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/MachineLearningIT.java
index 4bc4f3641ac09..73c146c954f62 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/MachineLearningIT.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/MachineLearningIT.java
@@ -63,6 +63,8 @@
import org.elasticsearch.client.ml.GetJobStatsResponse;
import org.elasticsearch.client.ml.GetModelSnapshotsRequest;
import org.elasticsearch.client.ml.GetModelSnapshotsResponse;
+import org.elasticsearch.client.ml.MlInfoRequest;
+import org.elasticsearch.client.ml.MlInfoResponse;
import org.elasticsearch.client.ml.OpenJobRequest;
import org.elasticsearch.client.ml.OpenJobResponse;
import org.elasticsearch.client.ml.PostCalendarEventRequest;
@@ -137,6 +139,7 @@
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
public class MachineLearningIT extends ESRestHighLevelClientTestCase {
@@ -1282,6 +1285,16 @@ public void testDeleteFilter() throws Exception {
assertThat(exception.status().getStatus(), equalTo(404));
}
+ public void testGetMlInfo() throws Exception {
+ MachineLearningClient machineLearningClient = highLevelClient().machineLearning();
+
+ MlInfoResponse infoResponse = execute(new MlInfoRequest(), machineLearningClient::getMlInfo, machineLearningClient::getMlInfoAsync);
+ Map info = infoResponse.getInfo();
+ assertThat(info, notNullValue());
+ assertTrue(info.containsKey("defaults"));
+ assertTrue(info.containsKey("limits"));
+ }
+
public static String randomValidJobId() {
CodepointSetGenerator generator = new CodepointSetGenerator("abcdefghijklmnopqrstuvwxyz0123456789".toCharArray());
return generator.ofCodePointsLength(random(), 10, 10);
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MlClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MlClientDocumentationIT.java
index e0fbf47281f26..0ef6c8d682806 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MlClientDocumentationIT.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MlClientDocumentationIT.java
@@ -78,6 +78,8 @@
import org.elasticsearch.client.ml.GetOverallBucketsResponse;
import org.elasticsearch.client.ml.GetRecordsRequest;
import org.elasticsearch.client.ml.GetRecordsResponse;
+import org.elasticsearch.client.ml.MlInfoRequest;
+import org.elasticsearch.client.ml.MlInfoResponse;
import org.elasticsearch.client.ml.OpenJobRequest;
import org.elasticsearch.client.ml.OpenJobResponse;
import org.elasticsearch.client.ml.PostCalendarEventRequest;
@@ -3003,6 +3005,55 @@ public void onFailure(Exception e) {
}
}
+ public void testGetMlInfo() throws Exception {
+ RestHighLevelClient client = highLevelClient();
+
+ {
+ // tag::get-ml-info-request
+ MlInfoRequest request = new MlInfoRequest(); // <1>
+ // end::get-ml-info-request
+
+ // tag::get-ml-info-execute
+ MlInfoResponse response = client.machineLearning()
+ .getMlInfo(request, RequestOptions.DEFAULT);
+ // end::get-ml-info-execute
+
+ // tag::get-ml-info-response
+ final Map info = response.getInfo();// <1>
+ // end::get-ml-info-response
+ assertTrue(info.containsKey("defaults"));
+ assertTrue(info.containsKey("limits"));
+ }
+ {
+ MlInfoRequest request = new MlInfoRequest();
+
+ // tag::get-ml-info-execute-listener
+ ActionListener listener = new ActionListener() {
+ @Override
+ public void onResponse(MlInfoResponse response) {
+ // <1>
+ }
+
+ @Override
+ public void onFailure(Exception e) {
+ // <2>
+ }
+ };
+ // end::get-ml-info-execute-listener
+
+ // Replace the empty listener by a blocking listener in test
+ final CountDownLatch latch = new CountDownLatch(1);
+ listener = new LatchedActionListener<>(listener, latch);
+
+ // tag::get-ml-info-execute-async
+ client.machineLearning()
+ .getMlInfoAsync(request, RequestOptions.DEFAULT, listener); // <1>
+ // end::get-ml-info-execute-async
+
+ assertTrue(latch.await(30L, TimeUnit.SECONDS));
+ }
+ }
+
private String createFilter(RestHighLevelClient client) throws IOException {
MlFilter.Builder filterBuilder = MlFilter.builder("my_safe_domains")
.setDescription("A list of safe domains")
diff --git a/docs/java-rest/high-level/ml/get-info.asciidoc b/docs/java-rest/high-level/ml/get-info.asciidoc
new file mode 100644
index 0000000000000..42da753329415
--- /dev/null
+++ b/docs/java-rest/high-level/ml/get-info.asciidoc
@@ -0,0 +1,33 @@
+--
+:api: get-ml-info
+:request: MlInfoRequest
+:response: MlInfoResponse
+--
+[id="{upid}-{api}"]
+=== ML Get Info API
+
+The ML Get API provides defaults and limits used internally by {ml}.
+These may be useful to a user interface that needs to interpret machine learning
+configurations where certain fields are missing because the end user was happy with the default value.
+
+It accepts a +{request}+ object and responds with a +{response}+ object.
+
+[id="{upid}-{api}-request"]
+==== Get Info Request
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request]
+--------------------------------------------------
+<1> Constructing a new request
+
+[id="{upid}-{api}-response"]
+==== ML Get Info Response
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-response]
+--------------------------------------------------
+<1> `info` from the +{response}+ contains ml info details
+
+include::../execution.asciidoc[]
diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc
index cea713a8dd305..29af1454a0a2b 100644
--- a/docs/java-rest/high-level/supported-apis.asciidoc
+++ b/docs/java-rest/high-level/supported-apis.asciidoc
@@ -280,6 +280,7 @@ The Java High Level REST Client supports the following Machine Learning APIs:
* <<{upid}-delete-model-snapshot>>
* <<{upid}-revert-model-snapshot>>
* <<{upid}-update-model-snapshot>>
+* <<{upid}-get-ml-info>>
* <<{upid}-delete-expired-data>>
include::ml/put-job.asciidoc[]
@@ -322,6 +323,7 @@ include::ml/get-model-snapshots.asciidoc[]
include::ml/delete-model-snapshot.asciidoc[]
include::ml/revert-model-snapshot.asciidoc[]
include::ml/update-model-snapshot.asciidoc[]
+include::ml/get-info.asciidoc[]
include::ml/delete-expired-data.asciidoc[]
== Migration APIs
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/action/MlInfoActionResponseTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/action/MlInfoActionResponseTests.java
index 7fb216d445d15..fe59810b595a4 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/action/MlInfoActionResponseTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/action/MlInfoActionResponseTests.java
@@ -5,13 +5,33 @@
*/
package org.elasticsearch.xpack.core.ml.action;
-import org.elasticsearch.test.AbstractStreamableTestCase;
+import org.elasticsearch.client.ml.MlInfoResponse;
+import org.elasticsearch.common.xcontent.XContentParser;
+import org.elasticsearch.protocol.AbstractHlrcStreamableXContentTestCase;
import org.elasticsearch.xpack.core.ml.action.MlInfoAction.Response;
+import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
+import java.util.function.Predicate;
-public class MlInfoActionResponseTests extends AbstractStreamableTestCase {
+public class MlInfoActionResponseTests extends
+ AbstractHlrcStreamableXContentTestCase {
+
+ @Override
+ public MlInfoResponse doHlrcParseInstance(XContentParser parser) throws IOException {
+ return MlInfoResponse.fromXContent(parser);
+ }
+
+ @Override
+ public Response convertHlrcToInternal(MlInfoResponse instance) {
+ return new Response(instance.getInfo());
+ }
+
+ @Override
+ protected Predicate getRandomFieldsExcludeFilter() {
+ return p -> true;
+ }
@Override
protected Response createTestInstance() {