Skip to content

Commit 2a41c9f

Browse files
vladimirdolzhenkodroberts195
authored andcommitted
[HLRC] XPack ML info action (#35777)
Relates to #29827
1 parent 8029ae2 commit 2a41c9f

File tree

10 files changed

+266
-2
lines changed

10 files changed

+266
-2
lines changed

client/rest-high-level/src/main/java/org/elasticsearch/client/MLRequestConverters.java

+8
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import org.elasticsearch.client.ml.GetModelSnapshotsRequest;
5454
import org.elasticsearch.client.ml.GetOverallBucketsRequest;
5555
import org.elasticsearch.client.ml.GetRecordsRequest;
56+
import org.elasticsearch.client.ml.MlInfoRequest;
5657
import org.elasticsearch.client.ml.OpenJobRequest;
5758
import org.elasticsearch.client.ml.PostCalendarEventRequest;
5859
import org.elasticsearch.client.ml.PostDataRequest;
@@ -663,6 +664,13 @@ static Request deleteFilter(DeleteFilterRequest deleteFilterRequest) {
663664
return request;
664665
}
665666

667+
static Request mlInfo(MlInfoRequest infoRequest) {
668+
String endpoint = new EndpointBuilder()
669+
.addPathPartAsIs("_xpack", "ml", "info")
670+
.build();
671+
return new Request(HttpGet.METHOD_NAME, endpoint);
672+
}
673+
666674
static Request findFileStructure(FindFileStructureRequest findFileStructureRequest) {
667675
String endpoint = new EndpointBuilder()
668676
.addPathPartAsIs("_xpack")

client/rest-high-level/src/main/java/org/elasticsearch/client/MachineLearningClient.java

+40
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565
import org.elasticsearch.client.ml.GetOverallBucketsResponse;
6666
import org.elasticsearch.client.ml.GetRecordsRequest;
6767
import org.elasticsearch.client.ml.GetRecordsResponse;
68+
import org.elasticsearch.client.ml.MlInfoRequest;
69+
import org.elasticsearch.client.ml.MlInfoResponse;
6870
import org.elasticsearch.client.ml.OpenJobRequest;
6971
import org.elasticsearch.client.ml.OpenJobResponse;
7072
import org.elasticsearch.client.ml.PostCalendarEventRequest;
@@ -1758,6 +1760,44 @@ public void deleteFilterAsync(DeleteFilterRequest request, RequestOptions option
17581760
Collections.emptySet());
17591761
}
17601762

1763+
/**
1764+
* Gets Machine Learning information about default values and limits.
1765+
* <p>
1766+
* For additional info
1767+
* see <a href="http://www.elastic.co/guide/en/elasticsearch/reference/current/get-ml-info.html">Machine Learning info</a>
1768+
*
1769+
* @param request The request of Machine Learning info
1770+
* @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
1771+
* @return response info about default values and limits
1772+
* @throws IOException when there is a serialization issue sending the request or receiving the response
1773+
*/
1774+
public MlInfoResponse getMlInfo(MlInfoRequest request, RequestOptions options) throws IOException {
1775+
return restHighLevelClient.performRequestAndParseEntity(request,
1776+
MLRequestConverters::mlInfo,
1777+
options,
1778+
MlInfoResponse::fromXContent,
1779+
Collections.emptySet());
1780+
}
1781+
1782+
/**
1783+
* Gets Machine Learning information about default values and limits, asynchronously.
1784+
* <p>
1785+
* For additional info
1786+
* see <a href="http://www.elastic.co/guide/en/elasticsearch/reference/current/get-ml-info.html">Machine Learning info</a>
1787+
*
1788+
* @param request The request of Machine Learning info
1789+
* @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
1790+
* @param listener Listener to be notified upon request completion
1791+
*/
1792+
public void getMlInfoAsync(MlInfoRequest request, RequestOptions options, ActionListener<MlInfoResponse> listener) {
1793+
restHighLevelClient.performRequestAsyncAndParseEntity(request,
1794+
MLRequestConverters::mlInfo,
1795+
options,
1796+
MlInfoResponse::fromXContent,
1797+
listener,
1798+
Collections.emptySet());
1799+
}
1800+
17611801
/**
17621802
* Finds the structure of a file
17631803
* <p>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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+
20+
package org.elasticsearch.client.ml;
21+
22+
import org.elasticsearch.client.Validatable;
23+
24+
public class MlInfoRequest implements Validatable {
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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+
20+
package org.elasticsearch.client.ml;
21+
22+
import org.elasticsearch.client.Validatable;
23+
import org.elasticsearch.common.xcontent.XContentParser;
24+
25+
import java.io.IOException;
26+
import java.util.Map;
27+
import java.util.Objects;
28+
29+
public class MlInfoResponse implements Validatable {
30+
private final Map<String, Object> info;
31+
32+
private MlInfoResponse(Map<String, Object> info) {
33+
this.info = info;
34+
}
35+
36+
public Map<String, Object> getInfo() {
37+
return info;
38+
}
39+
40+
public static MlInfoResponse fromXContent(XContentParser parser) throws IOException {
41+
Map<String, Object> info = parser.map();
42+
return new MlInfoResponse(info);
43+
}
44+
45+
@Override
46+
public int hashCode() {
47+
return Objects.hash(info);
48+
}
49+
50+
@Override
51+
public boolean equals(Object obj) {
52+
if (obj == null) {
53+
return false;
54+
}
55+
if (getClass() != obj.getClass()) {
56+
return false;
57+
}
58+
MlInfoResponse other = (MlInfoResponse) obj;
59+
return Objects.equals(info, other.info);
60+
}
61+
}

client/rest-high-level/src/test/java/org/elasticsearch/client/MLRequestConvertersTests.java

+11
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import org.elasticsearch.client.ml.GetModelSnapshotsRequest;
5151
import org.elasticsearch.client.ml.GetOverallBucketsRequest;
5252
import org.elasticsearch.client.ml.GetRecordsRequest;
53+
import org.elasticsearch.client.ml.MlInfoRequest;
5354
import org.elasticsearch.client.ml.OpenJobRequest;
5455
import org.elasticsearch.client.ml.PostCalendarEventRequest;
5556
import org.elasticsearch.client.ml.PostDataRequest;
@@ -728,6 +729,16 @@ public void testDeleteFilter() {
728729
assertNull(request.getEntity());
729730
}
730731

732+
public void testMlInfo() {
733+
MlInfoRequest infoRequest = new MlInfoRequest();
734+
735+
Request request = MLRequestConverters.mlInfo(infoRequest);
736+
737+
assertEquals(HttpGet.METHOD_NAME, request.getMethod());
738+
assertThat(request.getEndpoint(), equalTo("/_xpack/ml/info"));
739+
assertNull(request.getEntity());
740+
}
741+
731742
public void testFindFileStructure() throws Exception {
732743

733744
String sample = randomAlphaOfLength(randomIntBetween(1000, 2000));

client/rest-high-level/src/test/java/org/elasticsearch/client/MachineLearningIT.java

+13
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
import org.elasticsearch.client.ml.GetJobStatsResponse;
6464
import org.elasticsearch.client.ml.GetModelSnapshotsRequest;
6565
import org.elasticsearch.client.ml.GetModelSnapshotsResponse;
66+
import org.elasticsearch.client.ml.MlInfoRequest;
67+
import org.elasticsearch.client.ml.MlInfoResponse;
6668
import org.elasticsearch.client.ml.OpenJobRequest;
6769
import org.elasticsearch.client.ml.OpenJobResponse;
6870
import org.elasticsearch.client.ml.PostCalendarEventRequest;
@@ -137,6 +139,7 @@
137139
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
138140
import static org.hamcrest.Matchers.hasSize;
139141
import static org.hamcrest.Matchers.is;
142+
import static org.hamcrest.Matchers.notNullValue;
140143

141144
public class MachineLearningIT extends ESRestHighLevelClientTestCase {
142145

@@ -1282,6 +1285,16 @@ public void testDeleteFilter() throws Exception {
12821285
assertThat(exception.status().getStatus(), equalTo(404));
12831286
}
12841287

1288+
public void testGetMlInfo() throws Exception {
1289+
MachineLearningClient machineLearningClient = highLevelClient().machineLearning();
1290+
1291+
MlInfoResponse infoResponse = execute(new MlInfoRequest(), machineLearningClient::getMlInfo, machineLearningClient::getMlInfoAsync);
1292+
Map<String, Object> info = infoResponse.getInfo();
1293+
assertThat(info, notNullValue());
1294+
assertTrue(info.containsKey("defaults"));
1295+
assertTrue(info.containsKey("limits"));
1296+
}
1297+
12851298
public static String randomValidJobId() {
12861299
CodepointSetGenerator generator = new CodepointSetGenerator("abcdefghijklmnopqrstuvwxyz0123456789".toCharArray());
12871300
return generator.ofCodePointsLength(random(), 10, 10);

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

+51
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@
7878
import org.elasticsearch.client.ml.GetOverallBucketsResponse;
7979
import org.elasticsearch.client.ml.GetRecordsRequest;
8080
import org.elasticsearch.client.ml.GetRecordsResponse;
81+
import org.elasticsearch.client.ml.MlInfoRequest;
82+
import org.elasticsearch.client.ml.MlInfoResponse;
8183
import org.elasticsearch.client.ml.OpenJobRequest;
8284
import org.elasticsearch.client.ml.OpenJobResponse;
8385
import org.elasticsearch.client.ml.PostCalendarEventRequest;
@@ -3003,6 +3005,55 @@ public void onFailure(Exception e) {
30033005
}
30043006
}
30053007

3008+
public void testGetMlInfo() throws Exception {
3009+
RestHighLevelClient client = highLevelClient();
3010+
3011+
{
3012+
// tag::get-ml-info-request
3013+
MlInfoRequest request = new MlInfoRequest(); // <1>
3014+
// end::get-ml-info-request
3015+
3016+
// tag::get-ml-info-execute
3017+
MlInfoResponse response = client.machineLearning()
3018+
.getMlInfo(request, RequestOptions.DEFAULT);
3019+
// end::get-ml-info-execute
3020+
3021+
// tag::get-ml-info-response
3022+
final Map<String, Object> info = response.getInfo();// <1>
3023+
// end::get-ml-info-response
3024+
assertTrue(info.containsKey("defaults"));
3025+
assertTrue(info.containsKey("limits"));
3026+
}
3027+
{
3028+
MlInfoRequest request = new MlInfoRequest();
3029+
3030+
// tag::get-ml-info-execute-listener
3031+
ActionListener<MlInfoResponse> listener = new ActionListener<MlInfoResponse>() {
3032+
@Override
3033+
public void onResponse(MlInfoResponse response) {
3034+
// <1>
3035+
}
3036+
3037+
@Override
3038+
public void onFailure(Exception e) {
3039+
// <2>
3040+
}
3041+
};
3042+
// end::get-ml-info-execute-listener
3043+
3044+
// Replace the empty listener by a blocking listener in test
3045+
final CountDownLatch latch = new CountDownLatch(1);
3046+
listener = new LatchedActionListener<>(listener, latch);
3047+
3048+
// tag::get-ml-info-execute-async
3049+
client.machineLearning()
3050+
.getMlInfoAsync(request, RequestOptions.DEFAULT, listener); // <1>
3051+
// end::get-ml-info-execute-async
3052+
3053+
assertTrue(latch.await(30L, TimeUnit.SECONDS));
3054+
}
3055+
}
3056+
30063057
private String createFilter(RestHighLevelClient client) throws IOException {
30073058
MlFilter.Builder filterBuilder = MlFilter.builder("my_safe_domains")
30083059
.setDescription("A list of safe domains")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--
2+
:api: get-ml-info
3+
:request: MlInfoRequest
4+
:response: MlInfoResponse
5+
--
6+
[id="{upid}-{api}"]
7+
=== ML Get Info API
8+
9+
The ML Get API provides defaults and limits used internally by {ml}.
10+
These may be useful to a user interface that needs to interpret machine learning
11+
configurations where certain fields are missing because the end user was happy with the default value.
12+
13+
It accepts a +{request}+ object and responds with a +{response}+ object.
14+
15+
[id="{upid}-{api}-request"]
16+
==== Get Info Request
17+
18+
["source","java",subs="attributes,callouts,macros"]
19+
--------------------------------------------------
20+
include-tagged::{doc-tests-file}[{api}-request]
21+
--------------------------------------------------
22+
<1> Constructing a new request
23+
24+
[id="{upid}-{api}-response"]
25+
==== ML Get Info Response
26+
27+
["source","java",subs="attributes,callouts,macros"]
28+
--------------------------------------------------
29+
include-tagged::{doc-tests-file}[{api}-response]
30+
--------------------------------------------------
31+
<1> `info` from the +{response}+ contains ml info details
32+
33+
include::../execution.asciidoc[]

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

+2
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ The Java High Level REST Client supports the following Machine Learning APIs:
284284
* <<{upid}-delete-model-snapshot>>
285285
* <<{upid}-revert-model-snapshot>>
286286
* <<{upid}-update-model-snapshot>>
287+
* <<{upid}-get-ml-info>>
287288
* <<{upid}-delete-expired-data>>
288289

289290
include::ml/put-job.asciidoc[]
@@ -326,6 +327,7 @@ include::ml/get-model-snapshots.asciidoc[]
326327
include::ml/delete-model-snapshot.asciidoc[]
327328
include::ml/revert-model-snapshot.asciidoc[]
328329
include::ml/update-model-snapshot.asciidoc[]
330+
include::ml/get-info.asciidoc[]
329331
include::ml/delete-expired-data.asciidoc[]
330332

331333
== Migration APIs

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/action/MlInfoActionResponseTests.java

+22-2
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,33 @@
55
*/
66
package org.elasticsearch.xpack.core.ml.action;
77

8-
import org.elasticsearch.test.AbstractStreamableTestCase;
8+
import org.elasticsearch.client.ml.MlInfoResponse;
9+
import org.elasticsearch.common.xcontent.XContentParser;
10+
import org.elasticsearch.protocol.AbstractHlrcStreamableXContentTestCase;
911
import org.elasticsearch.xpack.core.ml.action.MlInfoAction.Response;
1012

13+
import java.io.IOException;
1114
import java.util.HashMap;
1215
import java.util.Map;
16+
import java.util.function.Predicate;
1317

14-
public class MlInfoActionResponseTests extends AbstractStreamableTestCase<Response> {
18+
public class MlInfoActionResponseTests extends
19+
AbstractHlrcStreamableXContentTestCase<Response, MlInfoResponse> {
20+
21+
@Override
22+
public MlInfoResponse doHlrcParseInstance(XContentParser parser) throws IOException {
23+
return MlInfoResponse.fromXContent(parser);
24+
}
25+
26+
@Override
27+
public Response convertHlrcToInternal(MlInfoResponse instance) {
28+
return new Response(instance.getInfo());
29+
}
30+
31+
@Override
32+
protected Predicate<String> getRandomFieldsExcludeFilter() {
33+
return p -> true;
34+
}
1535

1636
@Override
1737
protected Response createTestInstance() {

0 commit comments

Comments
 (0)