diff --git a/client/rest-high-level/build.gradle b/client/rest-high-level/build.gradle
index a1260894bf7..65c5d094c71 100644
--- a/client/rest-high-level/build.gradle
+++ b/client/rest-high-level/build.gradle
@@ -70,3 +70,7 @@ forbiddenApisMain {
signaturesURLs += [PrecommitTasks.getResource('/forbidden/http-signatures.txt')]
signaturesURLs += [file('src/main/resources/forbidden/rest-high-level-signatures.txt').toURI().toURL()]
}
+
+integTestCluster {
+ setting 'xpack.license.self_generated.type', 'trial'
+}
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 9dbd4916c77..a6122b0681e 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
@@ -106,6 +106,7 @@ import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.VersionType;
import org.elasticsearch.index.rankeval.RankEvalRequest;
import org.elasticsearch.protocol.xpack.XPackInfoRequest;
+import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
import org.elasticsearch.protocol.xpack.XPackUsageRequest;
import org.elasticsearch.rest.action.search.RestSearchAction;
import org.elasticsearch.script.mustache.MultiSearchTemplateRequest;
@@ -1097,6 +1098,25 @@ final class RequestConverters {
return request;
}
+ static Request xPackWatcherPutWatch(PutWatchRequest putWatchRequest) {
+ String endpoint = new EndpointBuilder()
+ .addPathPartAsIs("_xpack")
+ .addPathPartAsIs("watcher")
+ .addPathPartAsIs("watch")
+ .addPathPart(putWatchRequest.getId())
+ .build();
+
+ Request request = new Request(HttpPut.METHOD_NAME, endpoint);
+ Params params = new Params(request).withVersion(putWatchRequest.getVersion());
+ if (putWatchRequest.isActive() == false) {
+ params.putParam("active", "false");
+ }
+ ContentType contentType = createContentType(putWatchRequest.xContentType());
+ BytesReference source = putWatchRequest.getSource();
+ request.setEntity(new ByteArrayEntity(source.toBytesRef().bytes, 0, source.length(), contentType));
+ return request;
+ }
+
static Request xpackUsage(XPackUsageRequest usageRequest) {
Request request = new Request(HttpGet.METHOD_NAME, "/_xpack/usage");
Params parameters = new Params(request);
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
new file mode 100644
index 00000000000..73c92ba5c45
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/WatcherClient.java
@@ -0,0 +1,64 @@
+/*
+ * 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.action.ActionListener;
+import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
+import org.elasticsearch.protocol.xpack.watcher.PutWatchResponse;
+
+import java.io.IOException;
+
+import static java.util.Collections.emptySet;
+
+public final class WatcherClient {
+
+ private final RestHighLevelClient restHighLevelClient;
+
+ WatcherClient(RestHighLevelClient restHighLevelClient) {
+ this.restHighLevelClient = restHighLevelClient;
+ }
+
+ /**
+ * Put a watch into the cluster
+ * 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 PutWatchResponse putWatch(PutWatchRequest request, RequestOptions options) throws IOException {
+ return restHighLevelClient.performRequestAndParseEntity(request, RequestConverters::xPackWatcherPutWatch, options,
+ PutWatchResponse::fromXContent, emptySet());
+ }
+
+ /**
+ * Asynchronously put a watch into the cluster
+ * 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 putWatchAsync(PutWatchRequest request, RequestOptions options,
+ ActionListener listener) {
+ restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::xPackWatcherPutWatch, options,
+ PutWatchResponse::fromXContent, listener, emptySet());
+ }
+}
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/XPackClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/XPackClient.java
index a497619b987..4acaadfdb85 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/XPackClient.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/XPackClient.java
@@ -39,10 +39,17 @@ import static java.util.Collections.emptySet;
* X-Pack APIs on elastic.co for more information.
*/
public final class XPackClient {
+
private final RestHighLevelClient restHighLevelClient;
+ private final WatcherClient watcherClient;
XPackClient(RestHighLevelClient restHighLevelClient) {
this.restHighLevelClient = restHighLevelClient;
+ this.watcherClient = new WatcherClient(restHighLevelClient);
+ }
+
+ public WatcherClient watcher() {
+ return watcherClient;
}
/**
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/PingAndInfoIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/PingAndInfoIT.java
index b45f52f9e44..5f38316fd75 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/PingAndInfoIT.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/PingAndInfoIT.java
@@ -66,13 +66,13 @@ public class PingAndInfoIT extends ESRestHighLevelClientTestCase {
assertEquals(mainResponse.getBuild().shortHash(), info.getBuildInfo().getHash());
- assertEquals("basic", info.getLicenseInfo().getType());
- assertEquals("basic", info.getLicenseInfo().getMode());
+ assertEquals("trial", info.getLicenseInfo().getType());
+ assertEquals("trial", info.getLicenseInfo().getMode());
assertEquals(LicenseStatus.ACTIVE, info.getLicenseInfo().getStatus());
FeatureSet graph = info.getFeatureSetsInfo().getFeatureSets().get("graph");
assertNotNull(graph.description());
- assertFalse(graph.available());
+ assertTrue(graph.available());
assertTrue(graph.enabled());
assertNull(graph.nativeCodeInfo());
FeatureSet monitoring = info.getFeatureSetsInfo().getFeatureSets().get("monitoring");
@@ -82,7 +82,7 @@ public class PingAndInfoIT extends ESRestHighLevelClientTestCase {
assertNull(monitoring.nativeCodeInfo());
FeatureSet ml = info.getFeatureSetsInfo().getFeatureSets().get("ml");
assertNotNull(ml.description());
- assertFalse(ml.available());
+ assertTrue(ml.available());
assertTrue(ml.enabled());
assertEquals(mainResponse.getVersion().toString(),
ml.nativeCodeInfo().get("version").toString().replace("-SNAPSHOT", ""));
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java
index fb4e3b22712..c1f47feb33d 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java
@@ -41,9 +41,9 @@ import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequ
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
+import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
-import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
@@ -125,6 +125,7 @@ import org.elasticsearch.index.rankeval.RankEvalSpec;
import org.elasticsearch.index.rankeval.RatedRequest;
import org.elasticsearch.index.rankeval.RestRankEvalAction;
import org.elasticsearch.protocol.xpack.XPackInfoRequest;
+import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
import org.elasticsearch.repositories.fs.FsRepository;
import org.elasticsearch.rest.action.search.RestSearchAction;
import org.elasticsearch.script.ScriptType;
@@ -145,6 +146,7 @@ import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.RandomObjects;
import org.hamcrest.CoreMatchers;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
@@ -2523,6 +2525,35 @@ public class RequestConvertersTests extends ESTestCase {
assertEquals(expectedParams, request.getParameters());
}
+ public void testXPackPutWatch() throws Exception {
+ PutWatchRequest putWatchRequest = new PutWatchRequest();
+ String watchId = randomAlphaOfLength(10);
+ putWatchRequest.setId(watchId);
+ String body = randomAlphaOfLength(20);
+ putWatchRequest.setSource(new BytesArray(body), XContentType.JSON);
+
+ Map expectedParams = new HashMap<>();
+ if (randomBoolean()) {
+ putWatchRequest.setActive(false);
+ expectedParams.put("active", "false");
+ }
+
+ if (randomBoolean()) {
+ long version = randomLongBetween(10, 100);
+ putWatchRequest.setVersion(version);
+ expectedParams.put("version", String.valueOf(version));
+ }
+
+ Request request = RequestConverters.xPackWatcherPutWatch(putWatchRequest);
+ assertEquals(HttpPut.METHOD_NAME, request.getMethod());
+ assertEquals("/_xpack/watcher/watch/" + watchId, request.getEndpoint());
+ assertEquals(expectedParams, request.getParameters());
+ assertThat(request.getEntity().getContentType().getValue(), is(XContentType.JSON.mediaTypeWithoutParameters()));
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ request.getEntity().writeTo(bos);
+ assertThat(bos.toString("UTF-8"), is(body));
+ }
+
/**
* Randomize the {@link FetchSourceContext} request parameters.
*/
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java
index 47870125aa2..5acc6f5552f 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java
@@ -767,7 +767,9 @@ public class RestHighLevelClientTests extends ESTestCase {
private static Stream> getSubClientMethods(String namespace, Class> clientClass) {
return Arrays.stream(clientClass.getMethods()).filter(method -> method.getDeclaringClass().equals(clientClass))
- .map(method -> Tuple.tuple(namespace + "." + toSnakeCase(method.getName()), method));
+ .map(method -> Tuple.tuple(namespace + "." + toSnakeCase(method.getName()), method))
+ .flatMap(tuple -> tuple.v2().getReturnType().getName().endsWith("Client")
+ ? getSubClientMethods(tuple.v1(), tuple.v2().getReturnType()) : Stream.of(tuple));
}
private static String toSnakeCase(String camelCase) {
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
new file mode 100644
index 00000000000..dec438a47ab
--- /dev/null
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/WatcherIT.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;
+
+import org.elasticsearch.common.bytes.BytesArray;
+import org.elasticsearch.common.bytes.BytesReference;
+import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
+import org.elasticsearch.protocol.xpack.watcher.PutWatchResponse;
+
+import static org.hamcrest.Matchers.is;
+
+public class WatcherIT extends ESRestHighLevelClientTestCase {
+
+ public void testPutWatch() throws Exception {
+ String watchId = randomAlphaOfLength(10);
+ String json = "{ \n" +
+ " \"trigger\": { \"schedule\": { \"interval\": \"10h\" } },\n" +
+ " \"input\": { \"none\": {} },\n" +
+ " \"actions\": { \"logme\": { \"logging\": { \"text\": \"{{ctx.payload}}\" } } }\n" +
+ "}";
+ BytesReference bytesReference = new BytesArray(json);
+ PutWatchRequest putWatchRequest = new PutWatchRequest(watchId, bytesReference, XContentType.JSON);
+ PutWatchResponse putWatchResponse = highLevelClient().xpack().watcher().putWatch(putWatchRequest, RequestOptions.DEFAULT);
+ assertThat(putWatchResponse.isCreated(), is(true));
+ assertThat(putWatchResponse.getId(), is(watchId));
+ assertThat(putWatchResponse.getVersion(), is(1L));
+ }
+
+}
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MiscellaneousDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MiscellaneousDocumentationIT.java
index a99b991620a..a9fe4aba2f7 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MiscellaneousDocumentationIT.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MiscellaneousDocumentationIT.java
@@ -39,11 +39,13 @@ import org.elasticsearch.protocol.xpack.XPackUsageRequest;
import org.elasticsearch.protocol.xpack.XPackUsageResponse;
import java.io.IOException;
+import java.time.Instant;
import java.util.EnumSet;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
/**
@@ -97,8 +99,7 @@ public class MiscellaneousDocumentationIT extends ESRestHighLevelClientTestCase
//tag::x-pack-info-response
BuildInfo build = response.getBuildInfo(); // <1>
LicenseInfo license = response.getLicenseInfo(); // <2>
- assertEquals(XPackInfoResponse.BASIC_SELF_GENERATED_LICENSE_EXPIRATION_MILLIS,
- license.getExpiryDate()); // <3>
+ assertThat(license.getExpiryDate(), is(greaterThan(Instant.now().toEpochMilli()))); // <3>
FeatureSetsInfo features = response.getFeatureSetsInfo(); // <4>
//end::x-pack-info-response
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
new file mode 100644
index 00000000000..df51d896cda
--- /dev/null
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/WatcherDocumentationIT.java
@@ -0,0 +1,92 @@
+/*
+ * 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.documentation;
+
+import org.elasticsearch.action.ActionListener;
+import org.elasticsearch.action.LatchedActionListener;
+import org.elasticsearch.client.ESRestHighLevelClientTestCase;
+import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.client.RestHighLevelClient;
+import org.elasticsearch.common.bytes.BytesArray;
+import org.elasticsearch.common.bytes.BytesReference;
+import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
+import org.elasticsearch.protocol.xpack.watcher.PutWatchResponse;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class WatcherDocumentationIT extends ESRestHighLevelClientTestCase {
+
+ public void testPutWatch() throws Exception {
+ RestHighLevelClient client = highLevelClient();
+
+ {
+ //tag::x-pack-put-watch-execute
+ // you can also use the WatchSourceBuilder from org.elasticsearch.plugin:x-pack-core to create a watch programmatically
+ BytesReference watch = new BytesArray("{ \n" +
+ " \"trigger\": { \"schedule\": { \"interval\": \"10h\" } },\n" +
+ " \"input\": { \"simple\": { \"foo\" : \"bar\" } },\n" +
+ " \"actions\": { \"logme\": { \"logging\": { \"text\": \"{{ctx.payload}}\" } } }\n" +
+ "}");
+ PutWatchRequest request = new PutWatchRequest("my_watch_id", watch, XContentType.JSON);
+ request.setActive(false); // <1>
+ PutWatchResponse response = client.xpack().watcher().putWatch(request, RequestOptions.DEFAULT);
+ //end::x-pack-put-watch-execute
+
+ //tag::x-pack-put-watch-response
+ String watchId = response.getId(); // <1>
+ boolean isCreated = response.isCreated(); // <2>
+ long version = response.getVersion(); // <3>
+ //end::x-pack-put-watch-response
+ }
+
+ {
+ BytesReference watch = new BytesArray("{ \n" +
+ " \"trigger\": { \"schedule\": { \"interval\": \"10h\" } },\n" +
+ " \"input\": { \"simple\": { \"foo\" : \"bar\" } },\n" +
+ " \"actions\": { \"logme\": { \"logging\": { \"text\": \"{{ctx.payload}}\" } } }\n" +
+ "}");
+ PutWatchRequest request = new PutWatchRequest("my_other_watch_id", watch, XContentType.JSON);
+ // tag::x-pack-put-watch-execute-listener
+ ActionListener listener = new ActionListener() {
+ @Override
+ public void onResponse(PutWatchResponse response) {
+ // <1>
+ }
+
+ @Override
+ public void onFailure(Exception e) {
+ // <2>
+ }
+ };
+ // end::x-pack-put-watch-execute-listener
+
+ // Replace the empty listener by a blocking listener in test
+ final CountDownLatch latch = new CountDownLatch(1);
+ listener = new LatchedActionListener<>(listener, latch);
+
+ // tag::x-pack-put-watch-execute-async
+ client.xpack().watcher().putWatchAsync(request, RequestOptions.DEFAULT, listener); // <1>
+ // end::x-pack-put-watch-execute-async
+
+ assertTrue(latch.await(30L, TimeUnit.SECONDS));
+ }
+ }
+}
diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc
index cf38040e865..d952870677b 100644
--- a/docs/java-rest/high-level/supported-apis.asciidoc
+++ b/docs/java-rest/high-level/supported-apis.asciidoc
@@ -57,7 +57,8 @@ The Java High Level REST Client supports the following Miscellaneous APIs:
include::miscellaneous/main.asciidoc[]
include::miscellaneous/ping.asciidoc[]
-include::miscellaneous/x-pack-info.asciidoc[]
+include::x-pack/x-pack-info.asciidoc[]
+include::x-pack/watcher/put-watch.asciidoc[]
== Indices APIs
diff --git a/docs/java-rest/high-level/x-pack/watcher/put-watch.asciidoc b/docs/java-rest/high-level/x-pack/watcher/put-watch.asciidoc
new file mode 100644
index 00000000000..c803c54eb5e
--- /dev/null
+++ b/docs/java-rest/high-level/x-pack/watcher/put-watch.asciidoc
@@ -0,0 +1,55 @@
+[[java-rest-high-x-pack-watcher-put-watch]]
+=== X-Pack Info API
+
+[[java-rest-high-x-pack-watcher-put-watch-execution]]
+==== Execution
+
+General information about the installed {watcher} features can be retrieved
+using the `watcher()` method:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/WatcherDocumentationIT.java[x-pack-put-watch-execute]
+--------------------------------------------------
+<1> Allows to store the watch, but to not trigger it. Defaults to `true`
+
+[[java-rest-high-x-pack-watcher-put-watch-response]]
+==== Response
+
+The returned `XPackPutWatchResponse` contain `created`, `id`,
+and `version` information.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/WatcherDocumentationIT.java[x-pack-put-watch-response]
+--------------------------------------------------
+<1> `_id` contains id of the watch
+<2> `created` is a boolean indicating whether the watch was created for the first time
+<3> `_version` returns the newly created version
+
+[[java-rest-high-x-pack-watcher-put-watch-async]]
+==== Asynchronous Execution
+
+This request can be executed asynchronously:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/WatcherDocumentationIT.java[x-pack-put-watch-execute-async]
+--------------------------------------------------
+<1> The `XPackPutWatchRequest` 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 `XPackPutWatchResponse` looks like:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/WatcherDocumentationIT.java[x-pack-put-watch-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
diff --git a/docs/java-rest/high-level/miscellaneous/x-pack-info.asciidoc b/docs/java-rest/high-level/x-pack/x-pack-info.asciidoc
similarity index 100%
rename from docs/java-rest/high-level/miscellaneous/x-pack-info.asciidoc
rename to docs/java-rest/high-level/x-pack/x-pack-info.asciidoc
diff --git a/docs/java-rest/high-level/miscellaneous/x-pack-usage.asciidoc b/docs/java-rest/high-level/x-pack/x-pack-usage.asciidoc
similarity index 100%
rename from docs/java-rest/high-level/miscellaneous/x-pack-usage.asciidoc
rename to docs/java-rest/high-level/x-pack/x-pack-usage.asciidoc
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/client/WatcherClient.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/client/WatcherClient.java
index 10c4f0fffc3..063f1f655a4 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/client/WatcherClient.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/client/WatcherClient.java
@@ -8,6 +8,8 @@ package org.elasticsearch.xpack.core.watcher.client;
import org.elasticsearch.action.ActionFuture;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.client.Client;
+import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
+import org.elasticsearch.protocol.xpack.watcher.PutWatchResponse;
import org.elasticsearch.xpack.core.watcher.transport.actions.ack.AckWatchAction;
import org.elasticsearch.xpack.core.watcher.transport.actions.ack.AckWatchRequest;
import org.elasticsearch.xpack.core.watcher.transport.actions.ack.AckWatchRequestBuilder;
@@ -29,9 +31,7 @@ import org.elasticsearch.xpack.core.watcher.transport.actions.get.GetWatchReques
import org.elasticsearch.xpack.core.watcher.transport.actions.get.GetWatchRequestBuilder;
import org.elasticsearch.xpack.core.watcher.transport.actions.get.GetWatchResponse;
import org.elasticsearch.xpack.core.watcher.transport.actions.put.PutWatchAction;
-import org.elasticsearch.xpack.core.watcher.transport.actions.put.PutWatchRequest;
import org.elasticsearch.xpack.core.watcher.transport.actions.put.PutWatchRequestBuilder;
-import org.elasticsearch.xpack.core.watcher.transport.actions.put.PutWatchResponse;
import org.elasticsearch.xpack.core.watcher.transport.actions.service.WatcherServiceAction;
import org.elasticsearch.xpack.core.watcher.transport.actions.service.WatcherServiceRequest;
import org.elasticsearch.xpack.core.watcher.transport.actions.service.WatcherServiceRequestBuilder;
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/PutWatchAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/PutWatchAction.java
index 56cedc457bd..509116b018e 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/PutWatchAction.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/PutWatchAction.java
@@ -6,6 +6,7 @@
package org.elasticsearch.xpack.core.watcher.transport.actions.put;
import org.elasticsearch.action.Action;
+import org.elasticsearch.protocol.xpack.watcher.PutWatchResponse;
/**
* This action puts an watch into the watch index and adds it to the scheduler
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/PutWatchRequestBuilder.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/PutWatchRequestBuilder.java
index 050ac38dbb0..840ff560fba 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/PutWatchRequestBuilder.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/put/PutWatchRequestBuilder.java
@@ -9,6 +9,8 @@ import org.elasticsearch.action.ActionRequestBuilder;
import org.elasticsearch.client.ElasticsearchClient;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
+import org.elasticsearch.protocol.xpack.watcher.PutWatchResponse;
import org.elasticsearch.xpack.core.watcher.client.WatchSourceBuilder;
public class PutWatchRequestBuilder extends ActionRequestBuilder {
@@ -43,7 +45,7 @@ public class PutWatchRequestBuilder extends ActionRequestBuilder PARSER
+ = new ObjectParser<>("x_pack_put_watch_response", PutWatchResponse::new);
+ static {
+ PARSER.declareString(PutWatchResponse::setId, new ParseField("_id"));
+ PARSER.declareLong(PutWatchResponse::setVersion, new ParseField("_version"));
+ PARSER.declareBoolean(PutWatchResponse::setCreated, new ParseField("created"));
+ }
+
+ private String id;
+ private long version;
+ private boolean created;
+
+ public PutWatchResponse() {
+ }
+
+ public PutWatchResponse(String id, long version, boolean created) {
+ this.id = id;
+ this.version = version;
+ this.created = created;
+ }
+
+ private void setId(String id) {
+ this.id = id;
+ }
+
+ private void setVersion(long version) {
+ this.version = version;
+ }
+
+ private void setCreated(boolean created) {
+ this.created = created;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public long getVersion() {
+ return version;
+ }
+
+ public boolean isCreated() {
+ return created;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ PutWatchResponse that = (PutWatchResponse) o;
+
+ return Objects.equals(id, that.id) && Objects.equals(version, that.version) && Objects.equals(created, that.created);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, version, created);
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ super.writeTo(out);
+ out.writeString(id);
+ out.writeVLong(version);
+ out.writeBoolean(created);
+ }
+
+ @Override
+ public void readFrom(StreamInput in) throws IOException {
+ super.readFrom(in);
+ id = in.readString();
+ version = in.readVLong();
+ created = in.readBoolean();
+ }
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+ return builder.startObject()
+ .field("_id", id)
+ .field("_version", version)
+ .field("created", created)
+ .endObject();
+ }
+
+ public static PutWatchResponse fromXContent(XContentParser parser) throws IOException {
+ return PARSER.parse(parser, null);
+ }
+
+}
diff --git a/x-pack/protocol/src/test/java/org/elasticsearch/protocol/xpack/watcher/PutWatchResponseTests.java b/x-pack/protocol/src/test/java/org/elasticsearch/protocol/xpack/watcher/PutWatchResponseTests.java
new file mode 100644
index 00000000000..d0aadef1611
--- /dev/null
+++ b/x-pack/protocol/src/test/java/org/elasticsearch/protocol/xpack/watcher/PutWatchResponseTests.java
@@ -0,0 +1,45 @@
+/*
+ * 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.watcher;
+
+import org.elasticsearch.common.xcontent.XContentParser;
+import org.elasticsearch.test.AbstractXContentTestCase;
+
+import java.io.IOException;
+
+public class PutWatchResponseTests extends AbstractXContentTestCase {
+
+ @Override
+ protected PutWatchResponse createTestInstance() {
+ String id = randomAlphaOfLength(10);
+ long version = randomLongBetween(1, 10);
+ boolean created = randomBoolean();
+ return new PutWatchResponse(id, version, created);
+ }
+
+ @Override
+ protected PutWatchResponse doParseInstance(XContentParser parser) throws IOException {
+ return PutWatchResponse.fromXContent(parser);
+ }
+
+ @Override
+ protected boolean supportsUnknownFields() {
+ return false;
+ }
+}