Skip to content

Commit

Permalink
[HLRC] XPack ML info action (#35777)
Browse files Browse the repository at this point in the history
Relates to #29827
  • Loading branch information
vladimirdolzhenko authored and droberts195 committed Nov 28, 2018
1 parent 8029ae2 commit 2a41c9f
Show file tree
Hide file tree
Showing 10 changed files with 266 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1758,6 +1760,44 @@ public void deleteFilterAsync(DeleteFilterRequest request, RequestOptions option
Collections.emptySet());
}

/**
* Gets Machine Learning information about default values and limits.
* <p>
* For additional info
* see <a href="http://www.elastic.co/guide/en/elasticsearch/reference/current/get-ml-info.html">Machine Learning info</a>
*
* @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.
* <p>
* For additional info
* see <a href="http://www.elastic.co/guide/en/elasticsearch/reference/current/get-ml-info.html">Machine Learning info</a>
*
* @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<MlInfoResponse> listener) {
restHighLevelClient.performRequestAsyncAndParseEntity(request,
MLRequestConverters::mlInfo,
options,
MlInfoResponse::fromXContent,
listener,
Collections.emptySet());
}

/**
* Finds the structure of a file
* <p>
Expand Down
Original file line number Diff line number Diff line change
@@ -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 {
}
Original file line number Diff line number Diff line change
@@ -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<String, Object> info;

private MlInfoResponse(Map<String, Object> info) {
this.info = info;
}

public Map<String, Object> getInfo() {
return info;
}

public static MlInfoResponse fromXContent(XContentParser parser) throws IOException {
Map<String, Object> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {

Expand Down Expand Up @@ -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<String, Object> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<String, Object> 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<MlInfoResponse> listener = new ActionListener<MlInfoResponse>() {
@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")
Expand Down
33 changes: 33 additions & 0 deletions docs/java-rest/high-level/ml/get-info.asciidoc
Original file line number Diff line number Diff line change
@@ -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[]
2 changes: 2 additions & 0 deletions docs/java-rest/high-level/supported-apis.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,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[]
Expand Down Expand Up @@ -326,6 +327,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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Response> {
public class MlInfoActionResponseTests extends
AbstractHlrcStreamableXContentTestCase<Response, MlInfoResponse> {

@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<String> getRandomFieldsExcludeFilter() {
return p -> true;
}

@Override
protected Response createTestInstance() {
Expand Down

0 comments on commit 2a41c9f

Please sign in to comment.