From e636dd67b6cca38617d0655e95915da460135784 Mon Sep 17 00:00:00 2001 From: Mark Tozzi Date: Mon, 29 Oct 2018 12:33:25 -0400 Subject: [PATCH] HLRC: Deactivate Watch API (#34192) (#34860) Relates to #29827 --- .../elasticsearch/client/WatcherClient.java | 31 +++++++++ .../client/WatcherRequestConverters.java | 12 ++++ .../watcher/DeactivateWatchRequest.java | 43 ++++++++++++ .../watcher/DeactivateWatchResponse.java | 65 +++++++++++++++++++ .../org/elasticsearch/client/WatcherIT.java | 21 ++++++ .../client/WatcherRequestConvertersTests.java | 10 +++ .../documentation/WatcherDocumentationIT.java | 55 ++++++++++++++++ .../watcher/DeactivateWatchRequestTests.java | 41 ++++++++++++ .../watcher/DeactivateWatchResponseTests.java | 58 +++++++++++++++++ .../high-level/supported-apis.asciidoc | 2 + .../watcher/deactivate-watch.asciidoc | 10 +++ 11 files changed, 348 insertions(+) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/watcher/DeactivateWatchRequest.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/watcher/DeactivateWatchResponse.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/watcher/DeactivateWatchRequestTests.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/watcher/DeactivateWatchResponseTests.java create mode 100644 docs/java-rest/high-level/watcher/deactivate-watch.asciidoc diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/WatcherClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/WatcherClient.java index 5378859a999a0..a2b11772c1277 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/WatcherClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/WatcherClient.java @@ -19,6 +19,8 @@ package org.elasticsearch.client; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.client.watcher.DeactivateWatchRequest; +import org.elasticsearch.client.watcher.DeactivateWatchResponse; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.client.watcher.ActivateWatchRequest; import org.elasticsearch.client.watcher.ActivateWatchResponse; @@ -125,6 +127,35 @@ public void putWatchAsync(PutWatchRequest request, RequestOptions options, PutWatchResponse::fromXContent, listener, emptySet()); } + /** + * Deactivate an existing watch + * See + * the docs for more. + * @param request the request + * @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 DeactivateWatchResponse deactivateWatch(DeactivateWatchRequest request, RequestOptions options) throws IOException { + return restHighLevelClient.performRequestAndParseEntity(request, WatcherRequestConverters::deactivateWatch, options, + DeactivateWatchResponse::fromXContent, emptySet()); + } + + /** + * Asynchronously deactivate an existing watch + * See + * the docs for more. + * + * @param request the request + * @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 deactivateWatchAsync(DeactivateWatchRequest request, RequestOptions options, + ActionListener listener) { + restHighLevelClient.performRequestAsyncAndParseEntity(request, WatcherRequestConverters::deactivateWatch, options, + DeactivateWatchResponse::fromXContent, listener, emptySet()); + } + /** * Deletes a watch from the cluster * See diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/WatcherRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/WatcherRequestConverters.java index 64ca53376d7b2..49764025273b6 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/WatcherRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/WatcherRequestConverters.java @@ -24,6 +24,7 @@ import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.ContentType; +import org.elasticsearch.client.watcher.DeactivateWatchRequest; import org.elasticsearch.client.watcher.ActivateWatchRequest; import org.elasticsearch.client.watcher.AckWatchRequest; import org.elasticsearch.client.watcher.StartWatchServiceRequest; @@ -75,6 +76,17 @@ static Request putWatch(PutWatchRequest putWatchRequest) { return request; } + static Request deactivateWatch(DeactivateWatchRequest deactivateWatchRequest) { + String endpoint = new RequestConverters.EndpointBuilder() + .addPathPartAsIs("_xpack") + .addPathPartAsIs("watcher") + .addPathPartAsIs("watch") + .addPathPart(deactivateWatchRequest.getWatchId()) + .addPathPartAsIs("_deactivate") + .build(); + return new Request(HttpPut.METHOD_NAME, endpoint); + } + static Request deleteWatch(DeleteWatchRequest deleteWatchRequest) { String endpoint = new RequestConverters.EndpointBuilder() .addPathPartAsIs("_xpack") diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/watcher/DeactivateWatchRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/watcher/DeactivateWatchRequest.java new file mode 100644 index 0000000000000..b20a56c361f8f --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/watcher/DeactivateWatchRequest.java @@ -0,0 +1,43 @@ +/* + * 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.watcher; + +import org.elasticsearch.client.Validatable; +import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest; + +import java.util.Objects; + +public class DeactivateWatchRequest implements Validatable { + private final String watchId; + + public DeactivateWatchRequest(String watchId) { + + Objects.requireNonNull(watchId, "watch id is missing"); + if (PutWatchRequest.isValidId(watchId) == false) { + throw new IllegalArgumentException("watch id contains whitespace"); + } + + this.watchId = watchId; + } + + public String getWatchId() { + return watchId; + } +} + diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/watcher/DeactivateWatchResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/watcher/DeactivateWatchResponse.java new file mode 100644 index 0000000000000..08edd211d5b8f --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/watcher/DeactivateWatchResponse.java @@ -0,0 +1,65 @@ +/* + * 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.watcher; + +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.xcontent.ConstructingObjectParser; +import org.elasticsearch.common.xcontent.XContentParser; + +import java.io.IOException; +import java.util.Objects; + +public class DeactivateWatchResponse { + private WatchStatus status; + + private static final ParseField STATUS_FIELD = new ParseField("status"); + private static final ConstructingObjectParser PARSER + = new ConstructingObjectParser<>("x_pack_deactivate_watch_response", true, + (fields) -> new DeactivateWatchResponse((WatchStatus) fields[0])); + static { + PARSER.declareObject(ConstructingObjectParser.constructorArg(), + (parser, context) -> WatchStatus.parse(parser), + STATUS_FIELD); + } + + public static DeactivateWatchResponse fromXContent(XContentParser parser) throws IOException { + return PARSER.parse(parser, null); + } + + public DeactivateWatchResponse(WatchStatus status) { + this.status = status; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + DeactivateWatchResponse that = (DeactivateWatchResponse) o; + return Objects.equals(status, that.status); + } + + @Override + public int hashCode() { + return Objects.hash(status); + } + + public WatchStatus getStatus() { + return status; + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/WatcherIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/WatcherIT.java index b1d3dc0103ca3..b069d211b2ee8 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/WatcherIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/WatcherIT.java @@ -19,6 +19,10 @@ package org.elasticsearch.client; import org.elasticsearch.ElasticsearchStatusException; +import org.elasticsearch.client.watcher.DeactivateWatchRequest; +import org.elasticsearch.client.watcher.DeactivateWatchResponse; +import org.elasticsearch.client.watcher.ActivateWatchRequest; +import org.elasticsearch.client.watcher.ActivateWatchResponse; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.client.watcher.AckWatchRequest; import org.elasticsearch.client.watcher.AckWatchResponse; @@ -73,6 +77,23 @@ private PutWatchResponse createWatch(String watchId) throws Exception { return highLevelClient().watcher().putWatch(putWatchRequest, RequestOptions.DEFAULT); } + public void testDeactivateWatch() throws Exception { + // Deactivate a watch that exists + String watchId = randomAlphaOfLength(10); + createWatch(watchId); + DeactivateWatchResponse response = highLevelClient().watcher().deactivateWatch( + new DeactivateWatchRequest(watchId), RequestOptions.DEFAULT); + assertThat(response.getStatus().state().isActive(), is(false)); + } + public void testDeactivateWatch404() throws Exception { + // Deactivate a watch that does not exist + String watchId = randomAlphaOfLength(10); + ElasticsearchStatusException exception = expectThrows(ElasticsearchStatusException.class, + () -> highLevelClient().watcher().deactivateWatch(new DeactivateWatchRequest(watchId), RequestOptions.DEFAULT)); + assertEquals(RestStatus.NOT_FOUND, exception.status()); + + } + public void testDeleteWatch() throws Exception { // delete watch that exists { diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/WatcherRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/WatcherRequestConvertersTests.java index 231e836bea1e0..75fde82065089 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/WatcherRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/WatcherRequestConvertersTests.java @@ -22,6 +22,7 @@ import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; +import org.elasticsearch.client.watcher.DeactivateWatchRequest; import org.elasticsearch.client.watcher.ActivateWatchRequest; import org.elasticsearch.client.watcher.AckWatchRequest; import org.elasticsearch.client.watcher.StartWatchServiceRequest; @@ -83,6 +84,15 @@ public void testPutWatch() throws Exception { assertThat(bos.toString("UTF-8"), is(body)); } + public void testDeactivateWatch() { + String watchId = randomAlphaOfLength(10); + DeactivateWatchRequest deactivateWatchRequest = new DeactivateWatchRequest(watchId); + Request request = WatcherRequestConverters.deactivateWatch(deactivateWatchRequest); + + assertEquals(HttpPut.METHOD_NAME, request.getMethod()); + assertEquals("/_xpack/watcher/watch/" + watchId + "/_deactivate", request.getEndpoint()); + } + public void testXPackDeleteWatch() { DeleteWatchRequest deleteWatchRequest = new DeleteWatchRequest(); String watchId = randomAlphaOfLength(10); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/WatcherDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/WatcherDocumentationIT.java index b9562754e9168..165bda95dfc3d 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/WatcherDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/WatcherDocumentationIT.java @@ -32,6 +32,8 @@ import org.elasticsearch.client.watcher.AckWatchResponse; import org.elasticsearch.client.watcher.ActionStatus; import org.elasticsearch.client.watcher.ActionStatus.AckStatus; +import org.elasticsearch.client.watcher.DeactivateWatchRequest; +import org.elasticsearch.client.watcher.DeactivateWatchResponse; import org.elasticsearch.client.watcher.StartWatchServiceRequest; import org.elasticsearch.client.watcher.StopWatchServiceRequest; import org.elasticsearch.client.watcher.WatchStatus; @@ -47,6 +49,8 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import static org.hamcrest.Matchers.is; + public class WatcherDocumentationIT extends ESRestHighLevelClientTestCase { public void testStartStopWatchService() throws Exception { @@ -297,6 +301,57 @@ public void onFailure(Exception e) { } } + public void testDeactivateWatch() throws Exception { + RestHighLevelClient client = highLevelClient(); + + { + BytesReference watch = new BytesArray("{ \n" + + " \"trigger\": { \"schedule\": { \"interval\": \"10h\" } },\n" + + " \"input\": { \"simple\": { \"foo\" : \"bar\" } },\n" + + " \"actions\": { \"logme\": { \"logging\": { \"text\": \"{{ctx.payload}}\" } } }\n" + + "}"); + PutWatchRequest putWatchRequest = new PutWatchRequest("my_watch_id", watch, XContentType.JSON); + client.watcher().putWatch(putWatchRequest, RequestOptions.DEFAULT); + } + + { + //tag::deactivate-watch-execute + DeactivateWatchRequest request = new DeactivateWatchRequest("my_watch_id"); + DeactivateWatchResponse response = client.watcher().deactivateWatch(request, RequestOptions.DEFAULT); + //end::deactivate-watch-execute + + assertThat(response.getStatus().state().isActive(), is(false)); + } + + { + DeactivateWatchRequest request = new DeactivateWatchRequest("my_watch_id"); + // tag::deactivate-watch-execute-listener + ActionListener listener = new ActionListener() { + @Override + public void onResponse(DeactivateWatchResponse response) { + // <1> + } + + @Override + public void onFailure(Exception e) { + // <2> + } + }; + // end::deactivate-watch-execute-listener + + // For testing, replace the empty listener by a blocking listener. + final CountDownLatch latch = new CountDownLatch(1); + listener = new LatchedActionListener<>(listener, latch); + + // tag::deactivate-watch-execute-async + client.watcher().deactivateWatchAsync(request, RequestOptions.DEFAULT, listener); // <1> + // end::deactivate-watch-execute-async + + assertTrue(latch.await(30L, TimeUnit.SECONDS)); + } + } + + public void testActivateWatch() throws Exception { RestHighLevelClient client = highLevelClient(); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/watcher/DeactivateWatchRequestTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/watcher/DeactivateWatchRequestTests.java new file mode 100644 index 0000000000000..d92a51f96c26a --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/watcher/DeactivateWatchRequestTests.java @@ -0,0 +1,41 @@ +/* + * 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.watcher; + +import org.elasticsearch.test.ESTestCase; + +import static org.hamcrest.Matchers.is; + +public class DeactivateWatchRequestTests extends ESTestCase { + + public void testNullId() { + NullPointerException actual = expectThrows(NullPointerException.class, () -> new DeactivateWatchRequest(null)); + assertNotNull(actual); + assertThat(actual.getMessage(), is("watch id is missing")); + } + + public void testInvalidId() { + IllegalArgumentException actual = expectThrows(IllegalArgumentException.class, + () -> new DeactivateWatchRequest("Watch id has spaces")); + assertNotNull(actual); + assertThat(actual.getMessage(), is("watch id contains whitespace")); + } + +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/watcher/DeactivateWatchResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/watcher/DeactivateWatchResponseTests.java new file mode 100644 index 0000000000000..dd56c8b054e64 --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/watcher/DeactivateWatchResponseTests.java @@ -0,0 +1,58 @@ +/* + * 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.watcher; + + +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.xcontent.NamedXContentRegistry; +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.test.ESTestCase; + +import java.io.IOException; + +public class DeactivateWatchResponseTests extends ESTestCase { + + public void testBasicParsing() throws IOException { + XContentType contentType = randomFrom(XContentType.values()); + int version = randomInt(); + ExecutionState executionState = randomFrom(ExecutionState.values()); + XContentBuilder builder = XContentFactory.contentBuilder(contentType).startObject() + .startObject("status") + .field("version", version) + .field("execution_state", executionState) + .endObject() + .endObject(); + BytesReference bytes = BytesReference.bytes(builder); + DeactivateWatchResponse response = parse(contentType, bytes); + WatchStatus status = response.getStatus(); + assertNotNull(status); + assertEquals(version, status.version()); + assertEquals(executionState, status.getExecutionState()); + } + + private DeactivateWatchResponse parse(XContentType contentType, BytesReference bytes) throws IOException { + XContentParser parser = XContentFactory.xContent(contentType) + .createParser(NamedXContentRegistry.EMPTY, null, bytes.streamInput()); + parser.nextToken(); + return DeactivateWatchResponse.fromXContent(parser); + } +} diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc index 0a58af636c40b..8f2718244c98d 100644 --- a/docs/java-rest/high-level/supported-apis.asciidoc +++ b/docs/java-rest/high-level/supported-apis.asciidoc @@ -352,6 +352,7 @@ The Java High Level REST Client supports the following Watcher APIs: * <<{upid}-stop-watch-service>> * <> * <> +* <> * <<{upid}-ack-watch>> * <<{upid}-activate-watch>> @@ -360,6 +361,7 @@ include::watcher/stop-watch-service.asciidoc[] include::watcher/put-watch.asciidoc[] include::watcher/delete-watch.asciidoc[] include::watcher/ack-watch.asciidoc[] +include::watcher/deactivate-watch.asciidoc[] include::watcher/activate-watch.asciidoc[] == Graph APIs diff --git a/docs/java-rest/high-level/watcher/deactivate-watch.asciidoc b/docs/java-rest/high-level/watcher/deactivate-watch.asciidoc new file mode 100644 index 0000000000000..673423b69b983 --- /dev/null +++ b/docs/java-rest/high-level/watcher/deactivate-watch.asciidoc @@ -0,0 +1,10 @@ +-- +:api: deactivate-watch +:request: deactivateWatchRequet +:response: deactivateWatchResponse +:doc-tests-file: {doc-tests}/WatcherDocumentationIT.java +-- +[[java-rest-high-watcher-deactivate-watch]] +=== Deactivate Watch API + +include::../execution.asciidoc[]