From 5a42c26d78099c98ff306ddb1841fcfe41c5d563 Mon Sep 17 00:00:00 2001 From: Andy Bristol Date: Tue, 4 Sep 2018 18:53:05 -0700 Subject: [PATCH 1/9] add start trial API to HLRC Introduces client-specific request and response classes that do not depend on the server The `type` parameter is named `licenseType` in the response class to be more descriptive. The parts that make up the acknowledged-required response are given slightly different names than their server-response types to be consistent with the naming in the put license API --- .../elasticsearch/client/LicenseClient.java | 27 +++ .../client/RequestConverters.java | 21 ++ .../client/license/PostStartTrialRequest.java | 46 +++++ .../license/PostStartTrialResponse.java | 189 ++++++++++++++++++ .../LicensingDocumentationIT.java | 71 +++++++ .../licensing/post-start-trial.asciidoc | 68 +++++++ .../high-level/supported-apis.asciidoc | 2 + 7 files changed, 424 insertions(+) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/license/PostStartTrialRequest.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/license/PostStartTrialResponse.java create mode 100644 docs/java-rest/high-level/licensing/post-start-trial.asciidoc diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseClient.java index ca6539daa0432..7f9ea54087215 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseClient.java @@ -22,6 +22,8 @@ import org.apache.http.HttpEntity; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.support.master.AcknowledgedResponse; +import org.elasticsearch.client.license.PostStartTrialRequest; +import org.elasticsearch.client.license.PostStartTrialResponse; import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.xcontent.DeprecationHandler; @@ -42,6 +44,7 @@ import java.nio.charset.StandardCharsets; import static java.util.Collections.emptySet; +import static java.util.Collections.singleton; /** * A wrapper for the {@link RestHighLevelClient} that provides methods for @@ -121,6 +124,30 @@ public void deleteLicenseAsync(DeleteLicenseRequest request, RequestOptions opti AcknowledgedResponse::fromXContent, listener, emptySet()); } + /** + * Starts a trial license on the cluster. + * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @return the response + * @throws IOException in case there is a problem sending the request or parsing back the response + */ + public PostStartTrialResponse postStartTrial(PostStartTrialRequest request, RequestOptions options) throws IOException { + return restHighLevelClient.performRequestAndParseEntity(request, RequestConverters::postStartTrial, options, + PostStartTrialResponse::fromXContent, singleton(403)); + } + + /** + * Asynchronously starts a trial license on the cluster. + * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @param listener the listener to be notified upon request completion + */ + public void postStartTrialAsync(PostStartTrialRequest request, + RequestOptions options, + ActionListener listener) { + + restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::postStartTrial, options, + PostStartTrialResponse::fromXContent, listener, singleton(403)); + } + /** * Converts an entire response into a json string * diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java index 41caf2625a231..ee1f5422a7cc7 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java @@ -88,6 +88,7 @@ import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.action.update.UpdateRequest; +import org.elasticsearch.client.license.PostStartTrialRequest; import org.elasticsearch.client.security.RefreshPolicy; import org.elasticsearch.cluster.health.ClusterHealthStatus; import org.elasticsearch.common.Nullable; @@ -1278,6 +1279,26 @@ static Request deleteLicense(DeleteLicenseRequest deleteLicenseRequest) { return request; } + static Request postStartTrial(PostStartTrialRequest postStartTrialRequest) { + final String endpoint = new EndpointBuilder() + .addPathPartAsIs("_xpack") + .addPathPartAsIs("license") + .addPathPartAsIs("start_trial") + .build(); + + final Request request = new Request(HttpPost.METHOD_NAME, endpoint); + + Params parameters = new Params(request); + if (postStartTrialRequest.isAcknowledge()) { + parameters.putParam("acknowledge", "true"); + } + if (postStartTrialRequest.getLicenseType() != null) { + parameters.putParam("type", postStartTrialRequest.getLicenseType()); + } + + return request; + } + static Request getMigrationAssistance(IndexUpgradeInfoRequest indexUpgradeInfoRequest) { EndpointBuilder endpointBuilder = new EndpointBuilder() .addPathPartAsIs("_xpack/migration/assistance") diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/license/PostStartTrialRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/license/PostStartTrialRequest.java new file mode 100644 index 0000000000000..9f0b2a0558cbe --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/license/PostStartTrialRequest.java @@ -0,0 +1,46 @@ +/* + * 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.license; + +import org.elasticsearch.client.Validatable; + +public class PostStartTrialRequest implements Validatable { + + private boolean acknowledge = false; + private String licenseType = null; + + public boolean isAcknowledge() { + return acknowledge; + } + + public PostStartTrialRequest setAcknowledge(boolean acknowledge) { + this.acknowledge = acknowledge; + return this; + } + + public String getLicenseType() { + return licenseType; + } + + public PostStartTrialRequest setLicenseType(String licenseType) { + this.licenseType = licenseType; + return this; + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/license/PostStartTrialResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/license/PostStartTrialResponse.java new file mode 100644 index 0000000000000..064ee26d2b459 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/license/PostStartTrialResponse.java @@ -0,0 +1,189 @@ +/* + * 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.license; + +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.collect.Tuple; +import org.elasticsearch.common.xcontent.ConstructingObjectParser; +import org.elasticsearch.common.xcontent.XContentParseException; +import org.elasticsearch.common.xcontent.XContentParser; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg; +import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg; + +public class PostStartTrialResponse { + + private static final ParseField ACKNOWLEDGED_FIELD = new ParseField("acknowledged"); + private static final ParseField TRIAL_WAS_STARTED_FIELD = new ParseField("trial_was_started"); + private static final ParseField LICENSE_TYPE_FIELD = new ParseField("type"); + private static final ParseField ERROR_MESSAGE_FIELD = new ParseField("error_message"); + private static final ParseField ACKNOWLEDGE_DETAILS_FIELD = new ParseField("acknowledge"); + private static final ParseField ACKNOWLEDGE_HEADER_FIELD = new ParseField("message"); + + private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( + "post_start_trial_response", + true, + (Object[] arguments, Void aVoid) -> { + final boolean acknowledged = (boolean) arguments[0]; + final boolean trialWasStarted = (boolean) arguments[1]; + final String licenseType = (String) arguments[2]; + final String errorMessage = (String) arguments[3]; + + @SuppressWarnings("unchecked") + final Tuple> acknowledgeDetails = (Tuple>) arguments[4]; + final String acknowledgeHeader; + final Map acknowledgeMessages; + + if (acknowledgeDetails != null) { + acknowledgeHeader = acknowledgeDetails.v1(); + acknowledgeMessages = acknowledgeDetails.v2(); + } else { + acknowledgeHeader = null; + acknowledgeMessages = null; + } + + return new PostStartTrialResponse(acknowledged, trialWasStarted, licenseType, errorMessage, acknowledgeHeader, + acknowledgeMessages); + } + ); + + static { + PARSER.declareBoolean(constructorArg(), ACKNOWLEDGED_FIELD); + PARSER.declareBoolean(constructorArg(), TRIAL_WAS_STARTED_FIELD); + PARSER.declareString(optionalConstructorArg(), LICENSE_TYPE_FIELD); + PARSER.declareString(optionalConstructorArg(), ERROR_MESSAGE_FIELD); + // todo consolidate this parsing with the parsing in PutLicenseResponse + PARSER.declareObject(optionalConstructorArg(), (parser, aVoid) -> { + Map acknowledgeMessages = new HashMap<>(); + String message = null; + XContentParser.Token token; + String currentFieldName = null; + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else { + if (currentFieldName == null) { + throw new XContentParseException(parser.getTokenLocation(), "expected message header or acknowledgement"); + } + if (ACKNOWLEDGE_HEADER_FIELD.getPreferredName().equals(currentFieldName)) { + if (token != XContentParser.Token.VALUE_STRING) { + throw new XContentParseException(parser.getTokenLocation(), "unexpected message header type"); + } + message = parser.text(); + } else if (token == XContentParser.Token.START_ARRAY){ + List acknowledgeMessagesList = new ArrayList<>(); + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + if (token != XContentParser.Token.VALUE_STRING) { + throw new XContentParseException(parser.getTokenLocation(), "unexpected acknowledgement text"); + } + acknowledgeMessagesList.add(parser.text()); + } + acknowledgeMessages.put(currentFieldName, acknowledgeMessagesList.toArray(new String[0])); + } else { + throw new XContentParseException(parser.getTokenLocation(), "unexpected acknowledgement type"); + } + } + } + return new Tuple<>(message, acknowledgeMessages); + }, ACKNOWLEDGE_DETAILS_FIELD); + } + + public static PostStartTrialResponse fromXContent(XContentParser parser) throws IOException { + return PARSER.apply(parser, null); + } + + private final boolean acknowledged; + private final boolean trialWasStarted; + private final String licenseType; + private final String errorMessage; + private final String acknowledgeHeader; + private final Map acknowledgeMessages; + + public PostStartTrialResponse(boolean acknowledged, + boolean trialWasStarted, + String licenseType, + String errorMessage, + String acknowledgeHeader, + Map acknowledgeMessages) { + + this.acknowledged = acknowledged; + this.trialWasStarted = trialWasStarted; + this.licenseType = licenseType; + this.errorMessage = errorMessage; + this.acknowledgeHeader = acknowledgeHeader; + this.acknowledgeMessages = acknowledgeMessages; + } + + /** + * Returns true if the request that corresponds to this response acknowledged license changes that would occur as a result of starting + * a trial license + */ + public boolean isAcknowledged() { + return acknowledged; + } + + /** + * Returns true if a trial license was started as a result of the request corresponding to this response. Returns false if the cluster + * did not start a trial, or a trial had already been started before the corresponding request was made + */ + public boolean isTrialWasStarted() { + return trialWasStarted; + } + + /** + * If a trial license was started as a result of the request corresponding to this response (see {@link #isTrialWasStarted()}) then + * returns the type of license that was started on the cluster. Returns null otherwise + */ + public String getLicenseType() { + return licenseType; + } + + /** + * If a trial license was not started as a result of the request corresponding to this response (see {@link #isTrialWasStarted()} then + * returns a brief message explaining why the trial could not be started. Returns false otherwise + */ + public String getErrorMessage() { + return errorMessage; + } + + /** + * If the request corresponding to this response did not acknowledge licensing changes that would result from starting a trial license + * (see {@link #isAcknowledged()}), returns a message describing how the user must acknowledge licensing changes as a result of + * such a request. Returns null otherwise + */ + public String getAcknowledgeHeader() { + return acknowledgeHeader; + } + + /** + * If the request corresponding to this response did not acknowledge licensing changes that would result from starting a trial license + * (see {@link #isAcknowledged()}, returns a map. The map's keys are names of commercial Elasticsearch features, and their values are + * messages about how those features will be affected by licensing changes as a result of starting a trial license + */ + public Map getAcknowledgeMessages() { + return acknowledgeMessages; + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java index 3737bd70a8dae..e2db5104f2cda 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java @@ -26,6 +26,8 @@ import org.elasticsearch.client.ESRestHighLevelClientTestCase; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.client.license.PostStartTrialRequest; +import org.elasticsearch.client.license.PostStartTrialResponse; import org.elasticsearch.common.Booleans; import org.elasticsearch.protocol.xpack.license.DeleteLicenseRequest; import org.elasticsearch.protocol.xpack.license.GetLicenseRequest; @@ -39,10 +41,13 @@ import java.util.concurrent.TimeUnit; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.core.Is.is; /** * Documentation for Licensing APIs in the high level java client. @@ -215,4 +220,70 @@ public void onFailure(Exception e) { assertThat(currentLicense, endsWith("}")); } } + + public void testPostStartTrial() throws Exception { + RestHighLevelClient client = highLevelClient(); + + { + // tag::post-start-trial-execute + PostStartTrialRequest request = new PostStartTrialRequest(); + request.setAcknowledge(true); + + PostStartTrialResponse response = client.license().postStartTrial(request, RequestOptions.DEFAULT); + // end::post-start-trial-execute + + // tag::post-start-trial-response + boolean acknowledged = response.isAcknowledged(); // <1> + boolean trialWasStarted = response.isTrialWasStarted(); // <2> + String licenseType = response.getLicenseType(); // <3> + String errorMessage = response.getErrorMessage(); // <4> + String acknowledgeHeader = response.getAcknowledgeHeader(); // <5> + Map acknowledgeMessages = response.getAcknowledgeMessages(); // <6> + // end::post-start-trial-response + + assertTrue(acknowledged); + assertFalse(trialWasStarted); + assertThat(licenseType, nullValue()); + assertThat(errorMessage, is("Operation failed: Trial was already activated.")); + assertThat(acknowledgeHeader, nullValue()); + assertThat(acknowledgeMessages, nullValue()); + } + + { + PostStartTrialRequest request = new PostStartTrialRequest(); + + // tag::post-start-trial-execute-listener + ActionListener listener = new ActionListener() { + @Override + public void onResponse(PostStartTrialResponse response) { + // <1> + } + + @Override + public void onFailure(Exception e) { + // <2> + } + }; + // end::post-start-trial-execute-listener + + final CountDownLatch latch = new CountDownLatch(1); + listener = new LatchedActionListener<>(listener, latch); + + // tag::post-start-trial-execute-async + client.license().postStartTrialAsync(request, RequestOptions.DEFAULT, listener); + // end::post-start-trial-execute-async + } + + // test when there are acknowledge messages + { + PostStartTrialResponse response = client.license().postStartTrial(new PostStartTrialRequest(), RequestOptions.DEFAULT); + assertFalse(response.isAcknowledged()); + assertFalse(response.isTrialWasStarted()); + assertThat(response.getLicenseType(), nullValue()); + assertThat(response.getErrorMessage(), is("Operation failed: Needs acknowledgement.")); + assertThat(response.getAcknowledgeHeader(), containsString("To begin your free trial, call /start_trial again and specify " + + "the \"acknowledge=true\" parameter.")); + assertThat(response.getAcknowledgeMessages().entrySet(), not(empty())); + } + } } diff --git a/docs/java-rest/high-level/licensing/post-start-trial.asciidoc b/docs/java-rest/high-level/licensing/post-start-trial.asciidoc new file mode 100644 index 0000000000000..6e5a3239604f1 --- /dev/null +++ b/docs/java-rest/high-level/licensing/post-start-trial.asciidoc @@ -0,0 +1,68 @@ +[[java-rest-high-post-start-trial]] +=== Post Start Trial + +[[java-rest-high-post-start-license-execution]] +==== Execution + +This API creates and enables a trial license using the `postStartTrial()` +method. + +["source","java",subs="attributes,callouts,macros"] +--------------------------------------------------- +include-tagged::{doc_tests}/LicensingDocumentationIT.java[post-start-trial-execute] +--------------------------------------------------- + +[[java-rest-high-post-start-license-response]] +==== Response + +The returned `PostStartTrialResponse` returns a field indicating whether the +trial was started. If it was started, the response returns a the type of +license started. If it was not started, it returns an error message describing +why. + +Acknowledgement messages may also be returned if this API was called without +the `acknowledge` flag set to `true`. In this case you need to display the +messages to the end user and if they agree, resubmit the license with the +`acknowledge` flag set to `true`. Please note that the request will still +return a 200 return code even if requires an acknowledgement. So, it is +necessary to check the `acknowledged` flag. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/LicensingDocumentationIT.java[post-start-trial-response] +-------------------------------------------------- +<1> Whether or not the request had the `acknowledge` flag set +<2> Whether or not this request caused a trial to start +<3> If this request caused a trial to start, which type of license it +registered +<4> If this request did not cause a trial to start, a message explaining why +<5> If the user's request did not have the `acknowledge` flag set, a summary +of the user acknowledgement require for this API +<6> If the user's request did not have the `acknowledge` flag set, contains +keys of commercial features and values of messages describing how they will +be affected by licensing changes as the result of starting a trial + +[[java-rest-high-post-start-trial-async]] +==== Asynchronous execution + +This request can be executed asynchronously: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/LicensingDocumentationIT.java[post-start-trial-execute-async] +-------------------------------------------------- + +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 `PostStartTrialResponse` looks like: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/LicensingDocumentationIT.java[post-start-trial-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 \ No newline at end of file diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc index 481a2470aa2d7..2820df0b289bd 100644 --- a/docs/java-rest/high-level/supported-apis.asciidoc +++ b/docs/java-rest/high-level/supported-apis.asciidoc @@ -201,10 +201,12 @@ The Java High Level REST Client supports the following Licensing APIs: * <> * <> * <> +* <> include::licensing/put-license.asciidoc[] include::licensing/get-license.asciidoc[] include::licensing/delete-license.asciidoc[] +include::licensing/post-start-trial.asciidoc[] == Machine Learning APIs From faba89754bff23c6637c46211646fbd3fdeaf6eb Mon Sep 17 00:00:00 2001 From: Andy Bristol Date: Mon, 17 Sep 2018 13:24:03 -0700 Subject: [PATCH 2/9] move converter to LicenseRequestConverters --- .../elasticsearch/client/LicenseClient.java | 4 ++-- .../client/LicenseRequestConverters.java | 22 +++++++++++++++++++ .../client/RequestConverters.java | 1 - 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseClient.java index 0ab9d2fa3564c..ef50140d9fbec 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseClient.java @@ -131,7 +131,7 @@ public void deleteLicenseAsync(DeleteLicenseRequest request, RequestOptions opti * @throws IOException in case there is a problem sending the request or parsing back the response */ public PostStartTrialResponse postStartTrial(PostStartTrialRequest request, RequestOptions options) throws IOException { - return restHighLevelClient.performRequestAndParseEntity(request, RequestConverters::postStartTrial, options, + return restHighLevelClient.performRequestAndParseEntity(request, LicenseRequestConverters::postStartTrial, options, PostStartTrialResponse::fromXContent, singleton(403)); } @@ -144,7 +144,7 @@ public void postStartTrialAsync(PostStartTrialRequest request, RequestOptions options, ActionListener listener) { - restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::postStartTrial, options, + restHighLevelClient.performRequestAsyncAndParseEntity(request, LicenseRequestConverters::postStartTrial, options, PostStartTrialResponse::fromXContent, listener, singleton(403)); } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseRequestConverters.java index 7c2c049324eab..34375f3f7a380 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseRequestConverters.java @@ -21,7 +21,9 @@ import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; +import org.elasticsearch.client.license.PostStartTrialRequest; import org.elasticsearch.protocol.xpack.license.DeleteLicenseRequest; import org.elasticsearch.protocol.xpack.license.GetLicenseRequest; import org.elasticsearch.protocol.xpack.license.PutLicenseRequest; @@ -61,4 +63,24 @@ static Request deleteLicense(DeleteLicenseRequest deleteLicenseRequest) { parameters.withMasterTimeout(deleteLicenseRequest.masterNodeTimeout()); return request; } + + static Request postStartTrial(PostStartTrialRequest postStartTrialRequest) { + final String endpoint = new RequestConverters.EndpointBuilder() + .addPathPartAsIs("_xpack") + .addPathPartAsIs("license") + .addPathPartAsIs("start_trial") + .build(); + + final Request request = new Request(HttpPost.METHOD_NAME, endpoint); + + RequestConverters.Params parameters = new RequestConverters.Params(request); + if (postStartTrialRequest.isAcknowledge()) { + parameters.putParam("acknowledge", "true"); + } + if (postStartTrialRequest.getLicenseType() != null) { + parameters.putParam("type", postStartTrialRequest.getLicenseType()); + } + + return request; + } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java index 804c16fed269f..840bc4f0c4d9f 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java @@ -72,7 +72,6 @@ import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.action.update.UpdateRequest; -import org.elasticsearch.client.license.PostStartTrialRequest; import org.elasticsearch.client.security.RefreshPolicy; import org.elasticsearch.cluster.health.ClusterHealthStatus; import org.elasticsearch.common.Nullable; From 5df42726f27bc340f8a25dfaa5735ae575fd47ad Mon Sep 17 00:00:00 2001 From: Andy Bristol Date: Mon, 17 Sep 2018 13:41:28 -0700 Subject: [PATCH 3/9] rename post start trial to just start trial --- .../elasticsearch/client/LicenseClient.java | 20 +++++------ .../client/LicenseRequestConverters.java | 10 +++--- ...ialRequest.java => StartTrialRequest.java} | 6 ++-- ...lResponse.java => StartTrialResponse.java} | 22 ++++++------ .../LicensingDocumentationIT.java | 36 +++++++++---------- ...rt-trial.asciidoc => start-trial.asciidoc} | 24 ++++++------- .../high-level/supported-apis.asciidoc | 4 +-- 7 files changed, 61 insertions(+), 61 deletions(-) rename client/rest-high-level/src/main/java/org/elasticsearch/client/license/{PostStartTrialRequest.java => StartTrialRequest.java} (86%) rename client/rest-high-level/src/main/java/org/elasticsearch/client/license/{PostStartTrialResponse.java => StartTrialResponse.java} (91%) rename docs/java-rest/high-level/licensing/{post-start-trial.asciidoc => start-trial.asciidoc} (75%) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseClient.java index ef50140d9fbec..1bf42f9ee2166 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseClient.java @@ -22,8 +22,8 @@ import org.apache.http.HttpEntity; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.support.master.AcknowledgedResponse; -import org.elasticsearch.client.license.PostStartTrialRequest; -import org.elasticsearch.client.license.PostStartTrialResponse; +import org.elasticsearch.client.license.StartTrialRequest; +import org.elasticsearch.client.license.StartTrialResponse; import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.xcontent.DeprecationHandler; @@ -130,9 +130,9 @@ public void deleteLicenseAsync(DeleteLicenseRequest request, RequestOptions opti * @return the response * @throws IOException in case there is a problem sending the request or parsing back the response */ - public PostStartTrialResponse postStartTrial(PostStartTrialRequest request, RequestOptions options) throws IOException { - return restHighLevelClient.performRequestAndParseEntity(request, LicenseRequestConverters::postStartTrial, options, - PostStartTrialResponse::fromXContent, singleton(403)); + public StartTrialResponse startTrial(StartTrialRequest request, RequestOptions options) throws IOException { + return restHighLevelClient.performRequestAndParseEntity(request, LicenseRequestConverters::startTrial, options, + StartTrialResponse::fromXContent, singleton(403)); } /** @@ -140,12 +140,12 @@ public PostStartTrialResponse postStartTrial(PostStartTrialRequest request, Requ * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized * @param listener the listener to be notified upon request completion */ - public void postStartTrialAsync(PostStartTrialRequest request, - RequestOptions options, - ActionListener listener) { + public void startTrialAsync(StartTrialRequest request, + RequestOptions options, + ActionListener listener) { - restHighLevelClient.performRequestAsyncAndParseEntity(request, LicenseRequestConverters::postStartTrial, options, - PostStartTrialResponse::fromXContent, listener, singleton(403)); + restHighLevelClient.performRequestAsyncAndParseEntity(request, LicenseRequestConverters::startTrial, options, + StartTrialResponse::fromXContent, listener, singleton(403)); } /** diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseRequestConverters.java index 34375f3f7a380..1d29fe6621b3f 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseRequestConverters.java @@ -23,7 +23,7 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; -import org.elasticsearch.client.license.PostStartTrialRequest; +import org.elasticsearch.client.license.StartTrialRequest; import org.elasticsearch.protocol.xpack.license.DeleteLicenseRequest; import org.elasticsearch.protocol.xpack.license.GetLicenseRequest; import org.elasticsearch.protocol.xpack.license.PutLicenseRequest; @@ -64,7 +64,7 @@ static Request deleteLicense(DeleteLicenseRequest deleteLicenseRequest) { return request; } - static Request postStartTrial(PostStartTrialRequest postStartTrialRequest) { + static Request startTrial(StartTrialRequest startTrialRequest) { final String endpoint = new RequestConverters.EndpointBuilder() .addPathPartAsIs("_xpack") .addPathPartAsIs("license") @@ -74,11 +74,11 @@ static Request postStartTrial(PostStartTrialRequest postStartTrialRequest) { final Request request = new Request(HttpPost.METHOD_NAME, endpoint); RequestConverters.Params parameters = new RequestConverters.Params(request); - if (postStartTrialRequest.isAcknowledge()) { + if (startTrialRequest.isAcknowledge()) { parameters.putParam("acknowledge", "true"); } - if (postStartTrialRequest.getLicenseType() != null) { - parameters.putParam("type", postStartTrialRequest.getLicenseType()); + if (startTrialRequest.getLicenseType() != null) { + parameters.putParam("type", startTrialRequest.getLicenseType()); } return request; diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/license/PostStartTrialRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialRequest.java similarity index 86% rename from client/rest-high-level/src/main/java/org/elasticsearch/client/license/PostStartTrialRequest.java rename to client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialRequest.java index 9f0b2a0558cbe..447d3d47d1c24 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/license/PostStartTrialRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialRequest.java @@ -21,7 +21,7 @@ import org.elasticsearch.client.Validatable; -public class PostStartTrialRequest implements Validatable { +public class StartTrialRequest implements Validatable { private boolean acknowledge = false; private String licenseType = null; @@ -30,7 +30,7 @@ public boolean isAcknowledge() { return acknowledge; } - public PostStartTrialRequest setAcknowledge(boolean acknowledge) { + public StartTrialRequest setAcknowledge(boolean acknowledge) { this.acknowledge = acknowledge; return this; } @@ -39,7 +39,7 @@ public String getLicenseType() { return licenseType; } - public PostStartTrialRequest setLicenseType(String licenseType) { + public StartTrialRequest setLicenseType(String licenseType) { this.licenseType = licenseType; return this; } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/license/PostStartTrialResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialResponse.java similarity index 91% rename from client/rest-high-level/src/main/java/org/elasticsearch/client/license/PostStartTrialResponse.java rename to client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialResponse.java index 064ee26d2b459..f206f604677c5 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/license/PostStartTrialResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialResponse.java @@ -34,7 +34,7 @@ import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg; import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg; -public class PostStartTrialResponse { +public class StartTrialResponse { private static final ParseField ACKNOWLEDGED_FIELD = new ParseField("acknowledged"); private static final ParseField TRIAL_WAS_STARTED_FIELD = new ParseField("trial_was_started"); @@ -43,8 +43,8 @@ public class PostStartTrialResponse { private static final ParseField ACKNOWLEDGE_DETAILS_FIELD = new ParseField("acknowledge"); private static final ParseField ACKNOWLEDGE_HEADER_FIELD = new ParseField("message"); - private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( - "post_start_trial_response", + private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( + "start_trial_response", true, (Object[] arguments, Void aVoid) -> { final boolean acknowledged = (boolean) arguments[0]; @@ -65,7 +65,7 @@ public class PostStartTrialResponse { acknowledgeMessages = null; } - return new PostStartTrialResponse(acknowledged, trialWasStarted, licenseType, errorMessage, acknowledgeHeader, + return new StartTrialResponse(acknowledged, trialWasStarted, licenseType, errorMessage, acknowledgeHeader, acknowledgeMessages); } ); @@ -111,7 +111,7 @@ public class PostStartTrialResponse { }, ACKNOWLEDGE_DETAILS_FIELD); } - public static PostStartTrialResponse fromXContent(XContentParser parser) throws IOException { + public static StartTrialResponse fromXContent(XContentParser parser) throws IOException { return PARSER.apply(parser, null); } @@ -122,12 +122,12 @@ public static PostStartTrialResponse fromXContent(XContentParser parser) throws private final String acknowledgeHeader; private final Map acknowledgeMessages; - public PostStartTrialResponse(boolean acknowledged, - boolean trialWasStarted, - String licenseType, - String errorMessage, - String acknowledgeHeader, - Map acknowledgeMessages) { + public StartTrialResponse(boolean acknowledged, + boolean trialWasStarted, + String licenseType, + String errorMessage, + String acknowledgeHeader, + Map acknowledgeMessages) { this.acknowledged = acknowledged; this.trialWasStarted = trialWasStarted; diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java index e2db5104f2cda..a095590edfa0a 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java @@ -26,8 +26,8 @@ import org.elasticsearch.client.ESRestHighLevelClientTestCase; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; -import org.elasticsearch.client.license.PostStartTrialRequest; -import org.elasticsearch.client.license.PostStartTrialResponse; +import org.elasticsearch.client.license.StartTrialRequest; +import org.elasticsearch.client.license.StartTrialResponse; import org.elasticsearch.common.Booleans; import org.elasticsearch.protocol.xpack.license.DeleteLicenseRequest; import org.elasticsearch.protocol.xpack.license.GetLicenseRequest; @@ -221,25 +221,25 @@ public void onFailure(Exception e) { } } - public void testPostStartTrial() throws Exception { + public void testStartTrial() throws Exception { RestHighLevelClient client = highLevelClient(); { - // tag::post-start-trial-execute - PostStartTrialRequest request = new PostStartTrialRequest(); + // tag::start-trial-execute + StartTrialRequest request = new StartTrialRequest(); request.setAcknowledge(true); - PostStartTrialResponse response = client.license().postStartTrial(request, RequestOptions.DEFAULT); - // end::post-start-trial-execute + StartTrialResponse response = client.license().startTrial(request, RequestOptions.DEFAULT); + // end::start-trial-execute - // tag::post-start-trial-response + // tag::start-trial-response boolean acknowledged = response.isAcknowledged(); // <1> boolean trialWasStarted = response.isTrialWasStarted(); // <2> String licenseType = response.getLicenseType(); // <3> String errorMessage = response.getErrorMessage(); // <4> String acknowledgeHeader = response.getAcknowledgeHeader(); // <5> Map acknowledgeMessages = response.getAcknowledgeMessages(); // <6> - // end::post-start-trial-response + // end::start-trial-response assertTrue(acknowledged); assertFalse(trialWasStarted); @@ -250,12 +250,12 @@ public void testPostStartTrial() throws Exception { } { - PostStartTrialRequest request = new PostStartTrialRequest(); + StartTrialRequest request = new StartTrialRequest(); - // tag::post-start-trial-execute-listener - ActionListener listener = new ActionListener() { + // tag::start-trial-execute-listener + ActionListener listener = new ActionListener() { @Override - public void onResponse(PostStartTrialResponse response) { + public void onResponse(StartTrialResponse response) { // <1> } @@ -264,19 +264,19 @@ public void onFailure(Exception e) { // <2> } }; - // end::post-start-trial-execute-listener + // end::start-trial-execute-listener final CountDownLatch latch = new CountDownLatch(1); listener = new LatchedActionListener<>(listener, latch); - // tag::post-start-trial-execute-async - client.license().postStartTrialAsync(request, RequestOptions.DEFAULT, listener); - // end::post-start-trial-execute-async + // tag::start-trial-execute-async + client.license().startTrialAsync(request, RequestOptions.DEFAULT, listener); + // end::start-trial-execute-async } // test when there are acknowledge messages { - PostStartTrialResponse response = client.license().postStartTrial(new PostStartTrialRequest(), RequestOptions.DEFAULT); + StartTrialResponse response = client.license().startTrial(new StartTrialRequest(), RequestOptions.DEFAULT); assertFalse(response.isAcknowledged()); assertFalse(response.isTrialWasStarted()); assertThat(response.getLicenseType(), nullValue()); diff --git a/docs/java-rest/high-level/licensing/post-start-trial.asciidoc b/docs/java-rest/high-level/licensing/start-trial.asciidoc similarity index 75% rename from docs/java-rest/high-level/licensing/post-start-trial.asciidoc rename to docs/java-rest/high-level/licensing/start-trial.asciidoc index 6e5a3239604f1..8cc9417c3df76 100644 --- a/docs/java-rest/high-level/licensing/post-start-trial.asciidoc +++ b/docs/java-rest/high-level/licensing/start-trial.asciidoc @@ -1,21 +1,21 @@ -[[java-rest-high-post-start-trial]] -=== Post Start Trial +[[java-rest-high-start-trial]] +=== Start Trial -[[java-rest-high-post-start-license-execution]] +[[java-rest-high-start-license-execution]] ==== Execution -This API creates and enables a trial license using the `postStartTrial()` +This API creates and enables a trial license using the `startTrial()` method. ["source","java",subs="attributes,callouts,macros"] --------------------------------------------------- -include-tagged::{doc_tests}/LicensingDocumentationIT.java[post-start-trial-execute] +include-tagged::{doc_tests}/LicensingDocumentationIT.java[start-trial-execute] --------------------------------------------------- -[[java-rest-high-post-start-license-response]] +[[java-rest-high-start-license-response]] ==== Response -The returned `PostStartTrialResponse` returns a field indicating whether the +The returned `StartTrialResponse` returns a field indicating whether the trial was started. If it was started, the response returns a the type of license started. If it was not started, it returns an error message describing why. @@ -29,7 +29,7 @@ necessary to check the `acknowledged` flag. ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/LicensingDocumentationIT.java[post-start-trial-response] +include-tagged::{doc-tests}/LicensingDocumentationIT.java[start-trial-response] -------------------------------------------------- <1> Whether or not the request had the `acknowledge` flag set <2> Whether or not this request caused a trial to start @@ -42,14 +42,14 @@ of the user acknowledgement require for this API keys of commercial features and values of messages describing how they will be affected by licensing changes as the result of starting a trial -[[java-rest-high-post-start-trial-async]] +[[java-rest-high-start-trial-async]] ==== Asynchronous execution This request can be executed asynchronously: ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/LicensingDocumentationIT.java[post-start-trial-execute-async] +include-tagged::{doc-tests}/LicensingDocumentationIT.java[start-trial-execute-async] -------------------------------------------------- The asynchronous method does not block and returns immediately. Once it is @@ -57,11 +57,11 @@ 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 `PostStartTrialResponse` looks like: +A typical listener for `StartTrialResponse` looks like: ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/LicensingDocumentationIT.java[post-start-trial-execute-listener] +include-tagged::{doc-tests}/LicensingDocumentationIT.java[start-trial-execute-listener] -------------------------------------------------- <1> Called when the execution is successfully completed. The response is provided as an argument diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc index d0e0cb400a2f3..1814b9e4837c6 100644 --- a/docs/java-rest/high-level/supported-apis.asciidoc +++ b/docs/java-rest/high-level/supported-apis.asciidoc @@ -203,12 +203,12 @@ The Java High Level REST Client supports the following Licensing APIs: * <> * <> * <> -* <> +* <> include::licensing/put-license.asciidoc[] include::licensing/get-license.asciidoc[] include::licensing/delete-license.asciidoc[] -include::licensing/post-start-trial.asciidoc[] +include::licensing/start-trial.asciidoc[] == Machine Learning APIs From 07554dda3b4bb2e2871d913f00e3cead0cedeeb4 Mon Sep 17 00:00:00 2001 From: Andy Bristol Date: Mon, 17 Sep 2018 14:27:17 -0700 Subject: [PATCH 4/9] doc fixes --- .../high-level/licensing/start-trial.asciidoc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/java-rest/high-level/licensing/start-trial.asciidoc b/docs/java-rest/high-level/licensing/start-trial.asciidoc index 8cc9417c3df76..1e69a565506f4 100644 --- a/docs/java-rest/high-level/licensing/start-trial.asciidoc +++ b/docs/java-rest/high-level/licensing/start-trial.asciidoc @@ -1,7 +1,7 @@ [[java-rest-high-start-trial]] === Start Trial -[[java-rest-high-start-license-execution]] +[[java-rest-high-start-trial-execution]] ==== Execution This API creates and enables a trial license using the `startTrial()` @@ -9,10 +9,10 @@ method. ["source","java",subs="attributes,callouts,macros"] --------------------------------------------------- -include-tagged::{doc_tests}/LicensingDocumentationIT.java[start-trial-execute] +include-tagged::{doc-tests}/LicensingDocumentationIT.java[start-trial-execute] --------------------------------------------------- -[[java-rest-high-start-license-response]] +[[java-rest-high-start-trial-response]] ==== Response The returned `StartTrialResponse` returns a field indicating whether the @@ -22,9 +22,9 @@ why. Acknowledgement messages may also be returned if this API was called without the `acknowledge` flag set to `true`. In this case you need to display the -messages to the end user and if they agree, resubmit the license with the -`acknowledge` flag set to `true`. Please note that the request will still -return a 200 return code even if requires an acknowledgement. So, it is +messages to the end user and if they agree, resubmit the request with the +`acknowledge` flag set to `true`. Please note that the response will still +return a 200 return code even if it requires an acknowledgement. So, it is necessary to check the `acknowledged` flag. ["source","java",subs="attributes,callouts,macros"] @@ -37,7 +37,7 @@ include-tagged::{doc-tests}/LicensingDocumentationIT.java[start-trial-response] registered <4> If this request did not cause a trial to start, a message explaining why <5> If the user's request did not have the `acknowledge` flag set, a summary -of the user acknowledgement require for this API +of the user's acknowledgement required for this API <6> If the user's request did not have the `acknowledge` flag set, contains keys of commercial features and values of messages describing how they will be affected by licensing changes as the result of starting a trial From 74afddf266d32666b455385b35bd8158f6ef828d Mon Sep 17 00:00:00 2001 From: Andy Bristol Date: Wed, 19 Sep 2018 15:46:33 -0700 Subject: [PATCH 5/9] various review fixes --- .../client/LicenseRequestConverters.java | 24 ++------ .../client/RequestConverters.java | 8 ++- .../client/license/StartTrialRequest.java | 26 +++++---- .../client/license/StartTrialResponse.java | 19 ++----- .../client/LicenseRequestConvertersTests.java | 55 +++++++++++++++++++ .../LicensingDocumentationIT.java | 3 +- .../high-level/licensing/start-trial.asciidoc | 2 + 7 files changed, 90 insertions(+), 47 deletions(-) create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseRequestConvertersTests.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseRequestConverters.java index 1d29fe6621b3f..38047f65793ce 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/LicenseRequestConverters.java @@ -30,10 +30,7 @@ public class LicenseRequestConverters { static Request putLicense(PutLicenseRequest putLicenseRequest) { - String endpoint = new RequestConverters.EndpointBuilder() - .addPathPartAsIs("_xpack") - .addPathPartAsIs("license") - .build(); + String endpoint = new RequestConverters.EndpointBuilder().addPathPartAsIs("_xpack", "license").build(); Request request = new Request(HttpPut.METHOD_NAME, endpoint); RequestConverters.Params parameters = new RequestConverters.Params(request); parameters.withTimeout(putLicenseRequest.timeout()); @@ -46,10 +43,7 @@ static Request putLicense(PutLicenseRequest putLicenseRequest) { } static Request getLicense(GetLicenseRequest getLicenseRequest) { - String endpoint = new RequestConverters.EndpointBuilder() - .addPathPartAsIs("_xpack") - .addPathPartAsIs("license") - .build(); + String endpoint = new RequestConverters.EndpointBuilder().addPathPartAsIs("_xpack", "license").build(); Request request = new Request(HttpGet.METHOD_NAME, endpoint); RequestConverters.Params parameters = new RequestConverters.Params(request); parameters.withLocal(getLicenseRequest.local()); @@ -57,7 +51,8 @@ static Request getLicense(GetLicenseRequest getLicenseRequest) { } static Request deleteLicense(DeleteLicenseRequest deleteLicenseRequest) { - Request request = new Request(HttpDelete.METHOD_NAME, "/_xpack/license"); + String endpoint = new RequestConverters.EndpointBuilder().addPathPartAsIs("_xpack", "license").build(); + Request request = new Request(HttpDelete.METHOD_NAME, endpoint); RequestConverters.Params parameters = new RequestConverters.Params(request); parameters.withTimeout(deleteLicenseRequest.timeout()); parameters.withMasterTimeout(deleteLicenseRequest.masterNodeTimeout()); @@ -65,18 +60,11 @@ static Request deleteLicense(DeleteLicenseRequest deleteLicenseRequest) { } static Request startTrial(StartTrialRequest startTrialRequest) { - final String endpoint = new RequestConverters.EndpointBuilder() - .addPathPartAsIs("_xpack") - .addPathPartAsIs("license") - .addPathPartAsIs("start_trial") - .build(); - + final String endpoint = new RequestConverters.EndpointBuilder().addPathPartAsIs("_xpack", "license", "start_trial").build(); final Request request = new Request(HttpPost.METHOD_NAME, endpoint); RequestConverters.Params parameters = new RequestConverters.Params(request); - if (startTrialRequest.isAcknowledge()) { - parameters.putParam("acknowledge", "true"); - } + parameters.putParam("acknowledge", Boolean.toString(startTrialRequest.isAcknowledge())); if (startTrialRequest.getLicenseType() != null) { parameters.putParam("type", startTrialRequest.getLicenseType()); } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java index 840bc4f0c4d9f..ef0527fc78c2e 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java @@ -1300,9 +1300,11 @@ EndpointBuilder addCommaSeparatedPathParts(String[] parts) { return this; } - EndpointBuilder addPathPartAsIs(String part) { - if (Strings.hasLength(part)) { - joiner.add(part); + EndpointBuilder addPathPartAsIs(String... parts) { + for (String part : parts) { + if (Strings.hasLength(part)) { + joiner.add(part); + } } return this; } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialRequest.java index 447d3d47d1c24..57858f8de05a1 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialRequest.java @@ -20,27 +20,31 @@ package org.elasticsearch.client.license; import org.elasticsearch.client.Validatable; +import org.elasticsearch.common.Nullable; public class StartTrialRequest implements Validatable { - private boolean acknowledge = false; - private String licenseType = null; + private final boolean acknowledge; + private final String licenseType; - public boolean isAcknowledge() { - return acknowledge; + public StartTrialRequest() { + this(false); + } + + public StartTrialRequest(boolean acknowledge) { + this(acknowledge, null); } - public StartTrialRequest setAcknowledge(boolean acknowledge) { + public StartTrialRequest(boolean acknowledge, @Nullable String licenseType) { this.acknowledge = acknowledge; - return this; + this.licenseType = licenseType; } - public String getLicenseType() { - return licenseType; + public boolean isAcknowledge() { + return acknowledge; } - public StartTrialRequest setLicenseType(String licenseType) { - this.licenseType = licenseType; - return this; + public String getLicenseType() { + return licenseType; } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialResponse.java index f206f604677c5..f7040e56200e1 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialResponse.java @@ -36,13 +36,6 @@ public class StartTrialResponse { - private static final ParseField ACKNOWLEDGED_FIELD = new ParseField("acknowledged"); - private static final ParseField TRIAL_WAS_STARTED_FIELD = new ParseField("trial_was_started"); - private static final ParseField LICENSE_TYPE_FIELD = new ParseField("type"); - private static final ParseField ERROR_MESSAGE_FIELD = new ParseField("error_message"); - private static final ParseField ACKNOWLEDGE_DETAILS_FIELD = new ParseField("acknowledge"); - private static final ParseField ACKNOWLEDGE_HEADER_FIELD = new ParseField("message"); - private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( "start_trial_response", true, @@ -71,10 +64,10 @@ public class StartTrialResponse { ); static { - PARSER.declareBoolean(constructorArg(), ACKNOWLEDGED_FIELD); - PARSER.declareBoolean(constructorArg(), TRIAL_WAS_STARTED_FIELD); - PARSER.declareString(optionalConstructorArg(), LICENSE_TYPE_FIELD); - PARSER.declareString(optionalConstructorArg(), ERROR_MESSAGE_FIELD); + PARSER.declareBoolean(constructorArg(), new ParseField("acknowledged")); + PARSER.declareBoolean(constructorArg(), new ParseField("trial_was_started")); + PARSER.declareString(optionalConstructorArg(), new ParseField("type")); + PARSER.declareString(optionalConstructorArg(), new ParseField("error_message")); // todo consolidate this parsing with the parsing in PutLicenseResponse PARSER.declareObject(optionalConstructorArg(), (parser, aVoid) -> { Map acknowledgeMessages = new HashMap<>(); @@ -88,7 +81,7 @@ public class StartTrialResponse { if (currentFieldName == null) { throw new XContentParseException(parser.getTokenLocation(), "expected message header or acknowledgement"); } - if (ACKNOWLEDGE_HEADER_FIELD.getPreferredName().equals(currentFieldName)) { + if (new ParseField("message").getPreferredName().equals(currentFieldName)) { if (token != XContentParser.Token.VALUE_STRING) { throw new XContentParseException(parser.getTokenLocation(), "unexpected message header type"); } @@ -108,7 +101,7 @@ public class StartTrialResponse { } } return new Tuple<>(message, acknowledgeMessages); - }, ACKNOWLEDGE_DETAILS_FIELD); + }, new ParseField("acknowledge")); } public static StartTrialResponse fromXContent(XContentParser parser) throws IOException { diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseRequestConvertersTests.java new file mode 100644 index 0000000000000..277a27bbf8651 --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseRequestConvertersTests.java @@ -0,0 +1,55 @@ +/* + * 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; + +import org.apache.http.client.methods.HttpPost; +import org.elasticsearch.client.license.StartTrialRequest; +import org.elasticsearch.test.ESTestCase; + +import java.util.HashMap; +import java.util.Map; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.nullValue; + + +public class LicenseRequestConvertersTests extends ESTestCase { + + public void testStartTrial() { + final boolean acknowledge = randomBoolean(); + final String licenseType = randomBoolean() + ? randomAlphaOfLengthBetween(3, 10) + : null; + + final Map expectedParams = new HashMap<>(); + expectedParams.put("acknowledge", Boolean.toString(acknowledge)); + if (licenseType != null) { + expectedParams.put("type", licenseType); + } + + final StartTrialRequest hlrcRequest = new StartTrialRequest(acknowledge, licenseType); + final Request restRequest = LicenseRequestConverters.startTrial(hlrcRequest); + + assertThat(restRequest.getMethod(), equalTo(HttpPost.METHOD_NAME)); + assertThat(restRequest.getEndpoint(), equalTo("/_xpack/license/start_trial")); + assertThat(restRequest.getParameters(), equalTo(expectedParams)); + assertThat(restRequest.getEntity(), nullValue()); + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java index a095590edfa0a..f0105e0e4df7b 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java @@ -226,8 +226,7 @@ public void testStartTrial() throws Exception { { // tag::start-trial-execute - StartTrialRequest request = new StartTrialRequest(); - request.setAcknowledge(true); + StartTrialRequest request = new StartTrialRequest(true); // <1> StartTrialResponse response = client.license().startTrial(request, RequestOptions.DEFAULT); // end::start-trial-execute diff --git a/docs/java-rest/high-level/licensing/start-trial.asciidoc b/docs/java-rest/high-level/licensing/start-trial.asciidoc index 1e69a565506f4..0f198a391f07d 100644 --- a/docs/java-rest/high-level/licensing/start-trial.asciidoc +++ b/docs/java-rest/high-level/licensing/start-trial.asciidoc @@ -11,6 +11,8 @@ method. --------------------------------------------------- include-tagged::{doc-tests}/LicensingDocumentationIT.java[start-trial-execute] --------------------------------------------------- +<1> Sets the "acknowledge" parameter to true, indicating the user has +acknowledged that starting a trial license may affect commercial features [[java-rest-high-start-trial-response]] ==== Response From 20f8c2276d14924949c6e2670f73400e757c9f59 Mon Sep 17 00:00:00 2001 From: Andy Bristol Date: Wed, 19 Sep 2018 16:25:26 -0700 Subject: [PATCH 6/9] use XContentParser#map to parse acknowledgement messages, --- .../client/license/StartTrialResponse.java | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialResponse.java index f7040e56200e1..3b259960a3cd2 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/license/StartTrialResponse.java @@ -70,37 +70,43 @@ public class StartTrialResponse { PARSER.declareString(optionalConstructorArg(), new ParseField("error_message")); // todo consolidate this parsing with the parsing in PutLicenseResponse PARSER.declareObject(optionalConstructorArg(), (parser, aVoid) -> { - Map acknowledgeMessages = new HashMap<>(); + final Map acknowledgeMessages = new HashMap<>(); String message = null; - XContentParser.Token token; - String currentFieldName = null; - while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { - if (token == XContentParser.Token.FIELD_NAME) { - currentFieldName = parser.currentName(); - } else { - if (currentFieldName == null) { - throw new XContentParseException(parser.getTokenLocation(), "expected message header or acknowledgement"); + + final Map parsedMap = parser.map(); + for (Map.Entry entry : parsedMap.entrySet()) { + if (entry.getKey().equals("message")) { + if (entry.getValue() instanceof String) { + message = (String) entry.getValue(); + } else { + throw new XContentParseException(parser.getTokenLocation(), "unexpected acknowledgement header type"); } - if (new ParseField("message").getPreferredName().equals(currentFieldName)) { - if (token != XContentParser.Token.VALUE_STRING) { - throw new XContentParseException(parser.getTokenLocation(), "unexpected message header type"); - } - message = parser.text(); - } else if (token == XContentParser.Token.START_ARRAY){ - List acknowledgeMessagesList = new ArrayList<>(); - while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { - if (token != XContentParser.Token.VALUE_STRING) { - throw new XContentParseException(parser.getTokenLocation(), "unexpected acknowledgement text"); + } else { + if (entry.getValue() instanceof List) { + final List messageStrings = new ArrayList<>(); + @SuppressWarnings("unchecked") + final List messageObjects = (List) entry.getValue(); + for (Object messageObject : messageObjects) { + if (messageObject instanceof String) { + messageStrings.add((String) messageObject); + } else { + throw new XContentParseException(parser.getTokenLocation(), "expected text in acknowledgement message"); } - acknowledgeMessagesList.add(parser.text()); } - acknowledgeMessages.put(currentFieldName, acknowledgeMessagesList.toArray(new String[0])); + + acknowledgeMessages.put(entry.getKey(), messageStrings.toArray(new String[messageStrings.size()])); } else { - throw new XContentParseException(parser.getTokenLocation(), "unexpected acknowledgement type"); + throw new XContentParseException(parser.getTokenLocation(), "unexpected acknowledgement message type"); } } } + + if (message == null) { + throw new XContentParseException(parser.getTokenLocation(), "expected acknowledgement header"); + } + return new Tuple<>(message, acknowledgeMessages); + }, new ParseField("acknowledge")); } From a84d80bdddc3afa79e0c3828bd94731c076023e6 Mon Sep 17 00:00:00 2001 From: Andy Bristol Date: Wed, 19 Sep 2018 18:38:23 -0700 Subject: [PATCH 7/9] add hlrc license api IT --- .../org/elasticsearch/client/LicenseIT.java | 80 +++++++++++++++++++ .../LicensingDocumentationIT.java | 13 --- 2 files changed, 80 insertions(+), 13 deletions(-) create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseIT.java diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseIT.java new file mode 100644 index 0000000000000..b737512906665 --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseIT.java @@ -0,0 +1,80 @@ +/* + * 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; + +import org.elasticsearch.client.license.StartTrialRequest; +import org.elasticsearch.client.license.StartTrialResponse; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.Matchers.isEmptyOrNullString; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.empty; + +public class LicenseIT extends ESRestHighLevelClientTestCase { + + public void testStartTrial() throws Exception { + + // we don't test the case where we successfully start a trial because the integ test cluster generates one on startup + // and we don't have a good way to prevent that / work around it in this test project + + // case where we don't acknowledge trial license conditions + { + final StartTrialRequest request = new StartTrialRequest(); + final StartTrialResponse response = highLevelClient().license().startTrial(request, RequestOptions.DEFAULT); + + assertThat(response.isAcknowledged(), equalTo(false)); + assertThat(response.isTrialWasStarted(), equalTo(false)); + assertThat(response.getLicenseType(), nullValue()); + assertThat(response.getErrorMessage(), equalTo("Operation failed: Needs acknowledgement.")); + assertThat(response.getAcknowledgeHeader(), containsString("This API initiates a free 30-day trial for all platinum features")); + assertNotEmptyAcknowledgeMessages(response); + } + + // case where we acknowledge, but the trial is already started at cluster startup + { + final StartTrialRequest request = new StartTrialRequest(true); + final StartTrialResponse response = highLevelClient().license().startTrial(request, RequestOptions.DEFAULT); + + assertThat(response.isAcknowledged(), equalTo(true)); + assertThat(response.isTrialWasStarted(), equalTo(false)); + assertThat(response.getLicenseType(), nullValue()); + assertThat(response.getErrorMessage(), equalTo("Operation failed: Trial was already activated.")); + assertThat(response.getAcknowledgeHeader(), nullValue()); + assertThat(response.getAcknowledgeMessages(), nullValue()); + } + } + + private static void assertNotEmptyAcknowledgeMessages(StartTrialResponse response) { + assertThat(response.getAcknowledgeMessages().entrySet(), not(empty())); + for (Map.Entry entry : response.getAcknowledgeMessages().entrySet()) { + assertThat(entry.getKey(), not(isEmptyOrNullString())); + final List messages = Arrays.asList(entry.getValue()); + for (String message : messages) { + assertThat(message, not(isEmptyOrNullString())); + } + } + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java index f0105e0e4df7b..f7a506e426327 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java @@ -41,7 +41,6 @@ import java.util.concurrent.TimeUnit; import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.not; @@ -272,17 +271,5 @@ public void onFailure(Exception e) { client.license().startTrialAsync(request, RequestOptions.DEFAULT, listener); // end::start-trial-execute-async } - - // test when there are acknowledge messages - { - StartTrialResponse response = client.license().startTrial(new StartTrialRequest(), RequestOptions.DEFAULT); - assertFalse(response.isAcknowledged()); - assertFalse(response.isTrialWasStarted()); - assertThat(response.getLicenseType(), nullValue()); - assertThat(response.getErrorMessage(), is("Operation failed: Needs acknowledgement.")); - assertThat(response.getAcknowledgeHeader(), containsString("To begin your free trial, call /start_trial again and specify " + - "the \"acknowledge=true\" parameter.")); - assertThat(response.getAcknowledgeMessages().entrySet(), not(empty())); - } } } From 310fc41e61e2b9e9291c9e2f2808fcccf9b58f91 Mon Sep 17 00:00:00 2001 From: Andy Bristol Date: Mon, 15 Oct 2018 13:44:10 -0700 Subject: [PATCH 8/9] document snag with license tests --- .../test/java/org/elasticsearch/client/LicenseIT.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseIT.java index b737512906665..18010a0d18317 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseIT.java @@ -35,10 +35,15 @@ public class LicenseIT extends ESRestHighLevelClientTestCase { + /* + * todo there are some cases we can't test here because this gradle project starts the integ test cluster so that it'll generate + * a trial license at startup. we need to add a separate gradle project for the license-related tests so that we can start the + * integ test cluster without generating a trial license + */ + public void testStartTrial() throws Exception { - // we don't test the case where we successfully start a trial because the integ test cluster generates one on startup - // and we don't have a good way to prevent that / work around it in this test project + // todo add case where we successfully start a trial - see note above // case where we don't acknowledge trial license conditions { From 7288587aca43616ae52ba957ed5512cb6260e1f8 Mon Sep 17 00:00:00 2001 From: Andy Bristol Date: Tue, 16 Oct 2018 09:48:24 -0700 Subject: [PATCH 9/9] consolidate license IT --- .../org/elasticsearch/client/LicenseIT.java | 97 ++++++++++++- .../org/elasticsearch/client/LicensingIT.java | 130 ------------------ .../LicensingDocumentationIT.java | 2 +- 3 files changed, 91 insertions(+), 138 deletions(-) delete mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/LicensingIT.java diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseIT.java index 18010a0d18317..f804d17151167 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/LicenseIT.java @@ -19,13 +19,24 @@ package org.elasticsearch.client; +import org.elasticsearch.Build; +import org.elasticsearch.client.license.StartBasicRequest; +import org.elasticsearch.client.license.StartBasicResponse; import org.elasticsearch.client.license.StartTrialRequest; import org.elasticsearch.client.license.StartTrialResponse; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.collect.MapBuilder; +import org.elasticsearch.protocol.xpack.license.LicensesStatus; +import org.elasticsearch.protocol.xpack.license.PutLicenseRequest; +import org.elasticsearch.protocol.xpack.license.PutLicenseResponse; +import org.junit.After; +import org.junit.BeforeClass; +import java.io.IOException; import java.util.Arrays; -import java.util.List; import java.util.Map; +import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.nullValue; @@ -41,6 +52,17 @@ public class LicenseIT extends ESRestHighLevelClientTestCase { * integ test cluster without generating a trial license */ + @BeforeClass + public static void checkForSnapshot() { + assumeTrue("Trial license used to rollback is only valid when tested against snapshot/test builds", + Build.CURRENT.isSnapshot()); + } + + @After + public void rollbackToTrial() throws IOException { + putTrialLicense(); + } + public void testStartTrial() throws Exception { // todo add case where we successfully start a trial - see note above @@ -55,7 +77,7 @@ public void testStartTrial() throws Exception { assertThat(response.getLicenseType(), nullValue()); assertThat(response.getErrorMessage(), equalTo("Operation failed: Needs acknowledgement.")); assertThat(response.getAcknowledgeHeader(), containsString("This API initiates a free 30-day trial for all platinum features")); - assertNotEmptyAcknowledgeMessages(response); + assertNotEmptyAcknowledgeMessages(response.getAcknowledgeMessages()); } // case where we acknowledge, but the trial is already started at cluster startup @@ -72,12 +94,73 @@ public void testStartTrial() throws Exception { } } - private static void assertNotEmptyAcknowledgeMessages(StartTrialResponse response) { - assertThat(response.getAcknowledgeMessages().entrySet(), not(empty())); - for (Map.Entry entry : response.getAcknowledgeMessages().entrySet()) { + public static void putTrialLicense() throws IOException { + assumeTrue("Trial license is only valid when tested against snapshot/test builds", + Build.CURRENT.isSnapshot()); + + // use a hard-coded trial license for 20 yrs to be able to roll back from another licenses + final String licenseDefinition = Strings.toString(jsonBuilder() + .startObject() + .field("licenses", Arrays.asList( + MapBuilder.newMapBuilder() + .put("uid", "96fc37c6-6fc9-43e2-a40d-73143850cd72") + .put("type", "trial") + // 2018-10-16 07:02:48 UTC + .put("issue_date_in_millis", "1539673368158") + // 2038-10-11 07:02:48 UTC, 20 yrs later + .put("expiry_date_in_millis", "2170393368158") + .put("max_nodes", "5") + .put("issued_to", "client_rest-high-level_integTestCluster") + .put("issuer", "elasticsearch") + .put("start_date_in_millis", "-1") + .put("signature", + "AAAABAAAAA3FXON9kGmNqmH+ASDWAAAAIAo5/x6hrsGh1GqqrJmy4qgmEC7gK0U4zQ6q5ZEMhm4jAAABAAcdKHL0BfM2uqTgT7BDuFxX5lb" + + "t/bHDVJ421Wwgm5p3IMbw/W13iiAHz0hhDziF7acJbc/y65L+BKGtVC1gSSHeLDHaAD66VrjKxfc7VbGyJIAYBOdujf0rheurmaD3IcNo" + + "/tWDjCdtTwrNziFkorsGcPadBP5Yc6csk3/Q74DlfiYweMBxLUfkBERwxwd5OQS6ujGvl/4bb8p5zXvOw8vMSaAXSXXnExP6lam+0934W" + + "0kHvU7IGk+fCUjOaiSWKSoE4TEcAtVNYj/oRoRtfQ1KQGpdCHxTHs1BimdZaG0nBHDsvhYlVVLSvHN6QzqsHWgFDG6JJxhtU872oTRSUHA=") + .immutableMap())) + .endObject()); + + final PutLicenseRequest request = new PutLicenseRequest(); + request.setAcknowledge(true); + request.setLicenseDefinition(licenseDefinition); + final PutLicenseResponse response = highLevelClient().license().putLicense(request, RequestOptions.DEFAULT); + assertThat(response.isAcknowledged(), equalTo(true)); + assertThat(response.status(), equalTo(LicensesStatus.VALID)); + } + + public void testStartBasic() throws Exception { + // we don't test the case where we successfully start a basic because the integ test cluster generates one on startup + // and we don't have a good way to prevent that / work around it in this test project + // case where we don't acknowledge basic license conditions + { + final StartBasicRequest request = new StartBasicRequest(); + final StartBasicResponse response = highLevelClient().license().startBasic(request, RequestOptions.DEFAULT); + assertThat(response.isAcknowledged(), equalTo(false)); + assertThat(response.isBasicStarted(), equalTo(false)); + assertThat(response.getErrorMessage(), equalTo("Operation failed: Needs acknowledgement.")); + assertThat(response.getAcknowledgeMessage(), + containsString("This license update requires acknowledgement. " + + "To acknowledge the license, please read the following messages and call /start_basic again")); + assertNotEmptyAcknowledgeMessages(response.getAcknowledgeMessages()); + } + // case where we acknowledge and the basic is started successfully + { + final StartBasicRequest request = new StartBasicRequest(true); + final StartBasicResponse response = highLevelClient().license().startBasic(request, RequestOptions.DEFAULT); + assertThat(response.isAcknowledged(), equalTo(true)); + assertThat(response.isBasicStarted(), equalTo(true)); + assertThat(response.getErrorMessage(), nullValue()); + assertThat(response.getAcknowledgeMessage(), nullValue()); + assertThat(response.getAcknowledgeMessages().size(), equalTo(0)); + } + } + + private static void assertNotEmptyAcknowledgeMessages(Map acknowledgeMessages) { + assertThat(acknowledgeMessages.entrySet(), not(empty())); + for (Map.Entry entry : acknowledgeMessages.entrySet()) { assertThat(entry.getKey(), not(isEmptyOrNullString())); - final List messages = Arrays.asList(entry.getValue()); - for (String message : messages) { + for (String message : entry.getValue()) { assertThat(message, not(isEmptyOrNullString())); } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/LicensingIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/LicensingIT.java deleted file mode 100644 index 506eb71d66d96..0000000000000 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/LicensingIT.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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; - -import org.elasticsearch.Build; -import org.elasticsearch.client.license.StartBasicRequest; -import org.elasticsearch.client.license.StartBasicResponse; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.collect.MapBuilder; -import org.elasticsearch.protocol.xpack.license.LicensesStatus; -import org.elasticsearch.protocol.xpack.license.PutLicenseRequest; -import org.elasticsearch.protocol.xpack.license.PutLicenseResponse; -import org.junit.After; -import org.junit.BeforeClass; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.Matchers.isEmptyOrNullString; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.empty; - -public class LicensingIT extends ESRestHighLevelClientTestCase { - - @BeforeClass - public static void checkForSnapshot() { - assumeTrue("Trial license used to rollback is only valid when tested against snapshot/test builds", - Build.CURRENT.isSnapshot()); - } - - @After - public void rollbackToTrial() throws IOException { - putTrialLicense(); - } - - public static void putTrialLicense() throws IOException { - assumeTrue("Trial license is only valid when tested against snapshot/test builds", - Build.CURRENT.isSnapshot()); - - // use a hard-coded trial license for 20 yrs to be able to roll back from another licenses - final String licenseDefinition = Strings.toString(jsonBuilder() - .startObject() - .field("licenses", Arrays.asList( - MapBuilder.newMapBuilder() - .put("uid", "96fc37c6-6fc9-43e2-a40d-73143850cd72") - .put("type", "trial") - // 2018-10-16 07:02:48 UTC - .put("issue_date_in_millis", "1539673368158") - // 2038-10-11 07:02:48 UTC, 20 yrs later - .put("expiry_date_in_millis", "2170393368158") - .put("max_nodes", "5") - .put("issued_to", "client_rest-high-level_integTestCluster") - .put("issuer", "elasticsearch") - .put("start_date_in_millis", "-1") - .put("signature", - "AAAABAAAAA3FXON9kGmNqmH+ASDWAAAAIAo5/x6hrsGh1GqqrJmy4qgmEC7gK0U4zQ6q5ZEMhm4jAAABAAcdKHL0BfM2uqTgT7BDuFxX5lb" - + "t/bHDVJ421Wwgm5p3IMbw/W13iiAHz0hhDziF7acJbc/y65L+BKGtVC1gSSHeLDHaAD66VrjKxfc7VbGyJIAYBOdujf0rheurmaD3IcNo" - + "/tWDjCdtTwrNziFkorsGcPadBP5Yc6csk3/Q74DlfiYweMBxLUfkBERwxwd5OQS6ujGvl/4bb8p5zXvOw8vMSaAXSXXnExP6lam+0934W" - + "0kHvU7IGk+fCUjOaiSWKSoE4TEcAtVNYj/oRoRtfQ1KQGpdCHxTHs1BimdZaG0nBHDsvhYlVVLSvHN6QzqsHWgFDG6JJxhtU872oTRSUHA=") - .immutableMap())) - .endObject()); - - final PutLicenseRequest request = new PutLicenseRequest(); - request.setAcknowledge(true); - request.setLicenseDefinition(licenseDefinition); - final PutLicenseResponse response = highLevelClient().license().putLicense(request, RequestOptions.DEFAULT); - assertThat(response.isAcknowledged(), equalTo(true)); - assertThat(response.status(), equalTo(LicensesStatus.VALID)); - } - - public void testStartBasic() throws Exception { - // we don't test the case where we successfully start a basic because the integ test cluster generates one on startup - // and we don't have a good way to prevent that / work around it in this test project - // case where we don't acknowledge basic license conditions - { - final StartBasicRequest request = new StartBasicRequest(); - final StartBasicResponse response = highLevelClient().license().startBasic(request, RequestOptions.DEFAULT); - assertThat(response.isAcknowledged(), equalTo(false)); - assertThat(response.isBasicStarted(), equalTo(false)); - assertThat(response.getErrorMessage(), equalTo("Operation failed: Needs acknowledgement.")); - assertThat(response.getAcknowledgeMessage(), - containsString("This license update requires acknowledgement. " + - "To acknowledge the license, please read the following messages and call /start_basic again")); - assertNotEmptyAcknowledgeMessages(response); - } - // case where we acknowledge and the basic is started successfully - { - final StartBasicRequest request = new StartBasicRequest(true); - final StartBasicResponse response = highLevelClient().license().startBasic(request, RequestOptions.DEFAULT); - assertThat(response.isAcknowledged(), equalTo(true)); - assertThat(response.isBasicStarted(), equalTo(true)); - assertThat(response.getErrorMessage(), nullValue()); - assertThat(response.getAcknowledgeMessage(), nullValue()); - assertThat(response.getAcknowledgeMessages().size(), equalTo(0)); - } - } - - private static void assertNotEmptyAcknowledgeMessages(StartBasicResponse response) { - assertThat(response.getAcknowledgeMessages().entrySet(), not(empty())); - for (Map.Entry entry : response.getAcknowledgeMessages().entrySet()) { - assertThat(entry.getKey(), not(isEmptyOrNullString())); - final List messages = Arrays.asList(entry.getValue()); - for (String message : messages) { - assertThat(message, not(isEmptyOrNullString())); - } - } - } -} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java index 9f2626f8bbad8..9544dd14db6ab 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/LicensingDocumentationIT.java @@ -45,7 +45,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import static org.elasticsearch.client.LicensingIT.putTrialLicense; +import static org.elasticsearch.client.LicenseIT.putTrialLicense; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.hasSize;