HLRC: Add Delete License API (#32586)

Relates to #29827
This commit is contained in:
Yannick Welsch 2018-08-14 11:55:54 +02:00 committed by GitHub
parent 124c1f1358
commit 00b006f033
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 263 additions and 56 deletions

View File

@ -29,6 +29,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseRequest;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseResponse;
import org.elasticsearch.protocol.xpack.license.GetLicenseRequest;
import org.elasticsearch.protocol.xpack.license.GetLicenseResponse;
import org.elasticsearch.protocol.xpack.license.PutLicenseRequest;
@ -98,6 +100,27 @@ public final class LicenseClient {
response -> new GetLicenseResponse(convertResponseToJson(response)), listener, emptySet());
}
/**
* Deletes license from 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 DeleteLicenseResponse deleteLicense(DeleteLicenseRequest request, RequestOptions options) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(request, RequestConverters::deleteLicense, options,
DeleteLicenseResponse::fromXContent, emptySet());
}
/**
* Asynchronously deletes license from 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 deleteLicenseAsync(DeleteLicenseRequest request, RequestOptions options, ActionListener<DeleteLicenseResponse> listener) {
restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::deleteLicense, options,
DeleteLicenseResponse::fromXContent, listener, emptySet());
}
/**
* Converts an entire response into a json string
*

View File

@ -108,6 +108,7 @@ import org.elasticsearch.index.VersionType;
import org.elasticsearch.index.rankeval.RankEvalRequest;
import org.elasticsearch.protocol.xpack.XPackInfoRequest;
import org.elasticsearch.protocol.xpack.XPackUsageRequest;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseRequest;
import org.elasticsearch.protocol.xpack.license.GetLicenseRequest;
import org.elasticsearch.protocol.xpack.license.PutLicenseRequest;
import org.elasticsearch.protocol.xpack.migration.IndexUpgradeInfoRequest;
@ -1178,7 +1179,6 @@ final class RequestConverters {
return request;
}
static Request getLicense(GetLicenseRequest getLicenseRequest) {
String endpoint = new EndpointBuilder()
.addPathPartAsIs("_xpack")
@ -1190,6 +1190,14 @@ final class RequestConverters {
return request;
}
static Request deleteLicense(DeleteLicenseRequest deleteLicenseRequest) {
Request request = new Request(HttpDelete.METHOD_NAME, "/_xpack/license");
Params parameters = new Params(request);
parameters.withTimeout(deleteLicenseRequest.timeout());
parameters.withMasterTimeout(deleteLicenseRequest.masterNodeTimeout());
return request;
}
static Request putMachineLearningJob(PutJobRequest putJobRequest) throws IOException {
String endpoint = new EndpointBuilder()
.addPathPartAsIs("_xpack")

View File

@ -25,6 +25,9 @@ import org.elasticsearch.action.LatchedActionListener;
import org.elasticsearch.client.ESRestHighLevelClientTestCase;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.Booleans;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseRequest;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseResponse;
import org.elasticsearch.protocol.xpack.license.GetLicenseRequest;
import org.elasticsearch.protocol.xpack.license.GetLicenseResponse;
import org.elasticsearch.protocol.xpack.license.LicensesStatus;
@ -47,7 +50,7 @@ import static org.hamcrest.Matchers.startsWith;
*/
public class LicensingDocumentationIT extends ESRestHighLevelClientTestCase {
public void testPutLicense() throws Exception {
public void testLicense() throws Exception {
assumeTrue("License is only valid when tested against snapshot/test builds", Build.CURRENT.isSnapshot());
RestHighLevelClient client = highLevelClient();
String license = "{\"license\": {\"uid\":\"893361dc-9749-4997-93cb-802e3d7fa4a8\",\"type\":\"gold\"," +
@ -86,7 +89,7 @@ public class LicensingDocumentationIT extends ESRestHighLevelClientTestCase {
// tag::put-license-execute-listener
ActionListener<PutLicenseResponse> listener = new ActionListener<PutLicenseResponse>() {
@Override
public void onResponse(PutLicenseResponse indexResponse) {
public void onResponse(PutLicenseResponse putLicenseResponse) {
// <1>
}
@ -108,6 +111,51 @@ public class LicensingDocumentationIT extends ESRestHighLevelClientTestCase {
assertTrue(latch.await(30L, TimeUnit.SECONDS));
}
// we cannot actually delete the license, otherwise the remaining tests won't work
if (Booleans.isTrue("true")) {
return;
}
{
//tag::delete-license-execute
DeleteLicenseRequest request = new DeleteLicenseRequest();
DeleteLicenseResponse response = client.license().deleteLicense(request, RequestOptions.DEFAULT);
//end::delete-license-execute
//tag::delete-license-response
boolean acknowledged = response.isAcknowledged(); // <1>
//end::delete-license-response
assertTrue(acknowledged);
}
{
DeleteLicenseRequest request = new DeleteLicenseRequest();
// tag::delete-license-execute-listener
ActionListener<DeleteLicenseResponse> listener = new ActionListener<DeleteLicenseResponse>() {
@Override
public void onResponse(DeleteLicenseResponse deleteLicenseResponse) {
// <1>
}
@Override
public void onFailure(Exception e) {
// <2>
}
};
// end::delete-license-execute-listener
// Replace the empty listener by a blocking listener in test
final CountDownLatch latch = new CountDownLatch(1);
listener = new LatchedActionListener<>(listener, latch);
// tag::delete-license-execute-async
client.license().deleteLicenseAsync(
request, RequestOptions.DEFAULT, listener); // <1>
// end::delete-license-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS));
}
}
public void testGetLicense() throws Exception {

View File

@ -0,0 +1,51 @@
[[java-rest-high-delete-license]]
=== Delete License
[[java-rest-high-delete-license-execution]]
==== Execution
The license can be deleted using the `deleteLicense()` method:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/LicensingDocumentationIT.java[delete-license-execute]
--------------------------------------------------
[[java-rest-high-delete-license-response]]
==== Response
The returned `DeleteLicenseResponse` contains the `acknowledged` flag, which
returns true if the request was processed by all nodes.
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/LicensingDocumentationIT.java[delete-license-response]
--------------------------------------------------
<1> Check the acknowledge flag. It should be true if license deletion is acknowledged.
[[java-rest-high-delete-license-async]]
==== Asynchronous Execution
This request can be executed asynchronously:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/LicensingDocumentationIT.java[delete-license-execute-async]
--------------------------------------------------
<1> The `DeleteLicenseRequest` to execute and the `ActionListener` to use when
the execution completes
The asynchronous method does not block and returns immediately. Once it is
completed the `ActionListener` is called back using the `onResponse` method
if the execution successfully completed or using the `onFailure` method if
it failed.
A typical listener for `DeleteLicenseResponse` looks like:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/LicensingDocumentationIT.java[delete-license-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

View File

@ -194,9 +194,11 @@ The Java High Level REST Client supports the following Licensing APIs:
* <<java-rest-high-put-license>>
* <<java-rest-high-get-license>>
* <<java-rest-high-delete-license>>
include::licensing/put-license.asciidoc[]
include::licensing/get-license.asciidoc[]
include::licensing/delete-license.asciidoc[]
== Migration APIs

View File

@ -6,6 +6,7 @@
package org.elasticsearch.license;
import org.elasticsearch.action.Action;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseResponse;
public class DeleteLicenseAction extends Action<DeleteLicenseResponse> {

View File

@ -1,35 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.license;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.support.master.AcknowledgedRequest;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import java.io.IOException;
public class DeleteLicenseRequest extends AcknowledgedRequest<DeleteLicenseRequest> {
public DeleteLicenseRequest() {
}
@Override
public ActionRequestValidationException validate() {
return null;
}
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
}
}

View File

@ -7,6 +7,8 @@ package org.elasticsearch.license;
import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder;
import org.elasticsearch.client.ElasticsearchClient;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseRequest;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseResponse;
public class DeleteLicenseRequestBuilder extends AcknowledgedRequestBuilder<DeleteLicenseRequest, DeleteLicenseResponse,
DeleteLicenseRequestBuilder> {

View File

@ -1,18 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.license;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
public class DeleteLicenseResponse extends AcknowledgedResponse {
DeleteLicenseResponse() {
}
DeleteLicenseResponse(boolean acknowledged) {
super(acknowledged);
}
}

View File

@ -28,6 +28,7 @@ import org.elasticsearch.discovery.DiscoveryModule;
import org.elasticsearch.env.Environment;
import org.elasticsearch.gateway.GatewayService;
import org.elasticsearch.protocol.xpack.XPackInfoResponse;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseRequest;
import org.elasticsearch.protocol.xpack.license.LicensesStatus;
import org.elasticsearch.protocol.xpack.license.PutLicenseResponse;
import org.elasticsearch.watcher.ResourceWatcherService;

View File

@ -7,6 +7,8 @@ package org.elasticsearch.license;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.client.ElasticsearchClient;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseRequest;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseResponse;
import org.elasticsearch.protocol.xpack.license.GetLicenseRequest;
import org.elasticsearch.protocol.xpack.license.PutLicenseResponse;

View File

@ -6,6 +6,7 @@
package org.elasticsearch.license;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseRequest;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.action.RestToXContentListener;

View File

@ -17,6 +17,8 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseRequest;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseResponse;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;

View File

@ -11,6 +11,7 @@ import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseRequest;
import org.elasticsearch.protocol.xpack.license.LicensesStatus;
import org.elasticsearch.test.ESSingleNodeTestCase;
import org.elasticsearch.xpack.core.LocalStateCompositeXPackPlugin;

View File

@ -12,6 +12,7 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.node.Node;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.protocol.xpack.license.DeleteLicenseResponse;
import org.elasticsearch.protocol.xpack.license.LicensesStatus;
import org.elasticsearch.protocol.xpack.license.PutLicenseResponse;
import org.elasticsearch.test.ESSingleNodeTestCase;

View File

@ -0,0 +1,31 @@
/*
* 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.protocol.xpack.license;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.support.master.AcknowledgedRequest;
public class DeleteLicenseRequest extends AcknowledgedRequest<DeleteLicenseRequest> {
@Override
public ActionRequestValidationException validate() {
return null;
}
}

View File

@ -0,0 +1,36 @@
/*
* 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.protocol.xpack.license;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.common.xcontent.XContentParser;
public class DeleteLicenseResponse extends AcknowledgedResponse {
public DeleteLicenseResponse() {
}
public DeleteLicenseResponse(boolean acknowledged) {
super(acknowledged);
}
public static DeleteLicenseResponse fromXContent(XContentParser parser) {
return new DeleteLicenseResponse(parseAcknowledged(parser));
}
}

View File

@ -0,0 +1,50 @@
/*
* 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.protocol.xpack.license;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.test.AbstractStreamableXContentTestCase;
public class DeleteLicenseResponseTests extends AbstractStreamableXContentTestCase<DeleteLicenseResponse> {
@Override
protected boolean supportsUnknownFields() {
return true;
}
@Override
protected DeleteLicenseResponse createTestInstance() {
return new DeleteLicenseResponse(randomBoolean());
}
@Override
protected DeleteLicenseResponse doParseInstance(XContentParser parser) {
return DeleteLicenseResponse.fromXContent(parser);
}
@Override
protected DeleteLicenseResponse createBlankInstance() {
return new DeleteLicenseResponse();
}
@Override
protected DeleteLicenseResponse mutateInstance(DeleteLicenseResponse response) {
return new DeleteLicenseResponse(!response.isAcknowledged());
}
}