Skip to content

Commit 96b3ba7

Browse files
committed
Rest HL client: Add put watch action (elastic#32026)
Relates elastic#29827 This implementation behaves like the current transport client, that you basically cannot configure a Watch POJO representation as an argument to the put watch API, but only a bytes reference. You can use the the `WatchSourceBuilder` from the `org.elasticsearch.plugin:x-pack-core` dependency to build watches. This commit also changes the license type to trial, so that watcher is available in high level rest client tests.
1 parent f0a510d commit 96b3ba7

File tree

45 files changed

+564
-119
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+564
-119
lines changed

client/rest-high-level/build.gradle

+4
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,7 @@ forbiddenApisMain {
6868
signaturesURLs += [PrecommitTasks.getResource('/forbidden/http-signatures.txt')]
6969
signaturesURLs += [file('src/main/resources/forbidden/rest-high-level-signatures.txt').toURI().toURL()]
7070
}
71+
72+
integTestCluster {
73+
setting 'xpack.license.self_generated.type', 'trial'
74+
}

client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java

+20
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
import org.elasticsearch.index.VersionType;
106106
import org.elasticsearch.index.rankeval.RankEvalRequest;
107107
import org.elasticsearch.protocol.xpack.XPackInfoRequest;
108+
import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
108109
import org.elasticsearch.protocol.xpack.XPackUsageRequest;
109110
import org.elasticsearch.rest.action.search.RestSearchAction;
110111
import org.elasticsearch.script.mustache.MultiSearchTemplateRequest;
@@ -1093,6 +1094,25 @@ static Request xPackInfo(XPackInfoRequest infoRequest) {
10931094
return request;
10941095
}
10951096

1097+
static Request xPackWatcherPutWatch(PutWatchRequest putWatchRequest) {
1098+
String endpoint = new EndpointBuilder()
1099+
.addPathPartAsIs("_xpack")
1100+
.addPathPartAsIs("watcher")
1101+
.addPathPartAsIs("watch")
1102+
.addPathPart(putWatchRequest.getId())
1103+
.build();
1104+
1105+
Request request = new Request(HttpPut.METHOD_NAME, endpoint);
1106+
Params params = new Params(request).withVersion(putWatchRequest.getVersion());
1107+
if (putWatchRequest.isActive() == false) {
1108+
params.putParam("active", "false");
1109+
}
1110+
ContentType contentType = createContentType(putWatchRequest.xContentType());
1111+
BytesReference source = putWatchRequest.getSource();
1112+
request.setEntity(new ByteArrayEntity(source.toBytesRef().bytes, 0, source.length(), contentType));
1113+
return request;
1114+
}
1115+
10961116
static Request xpackUsage(XPackUsageRequest usageRequest) {
10971117
Request request = new Request(HttpGet.METHOD_NAME, "/_xpack/usage");
10981118
Params parameters = new Params(request);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.elasticsearch.client;
20+
21+
import org.elasticsearch.action.ActionListener;
22+
import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
23+
import org.elasticsearch.protocol.xpack.watcher.PutWatchResponse;
24+
25+
import java.io.IOException;
26+
27+
import static java.util.Collections.emptySet;
28+
29+
public final class WatcherClient {
30+
31+
private final RestHighLevelClient restHighLevelClient;
32+
33+
WatcherClient(RestHighLevelClient restHighLevelClient) {
34+
this.restHighLevelClient = restHighLevelClient;
35+
}
36+
37+
/**
38+
* Put a watch into the cluster
39+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/watcher-api-put-watch.html">
40+
* the docs</a> for more.
41+
* @param request the request
42+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
43+
* @return the response
44+
* @throws IOException in case there is a problem sending the request or parsing back the response
45+
*/
46+
public PutWatchResponse putWatch(PutWatchRequest request, RequestOptions options) throws IOException {
47+
return restHighLevelClient.performRequestAndParseEntity(request, RequestConverters::xPackWatcherPutWatch, options,
48+
PutWatchResponse::fromXContent, emptySet());
49+
}
50+
51+
/**
52+
* Asynchronously put a watch into the cluster
53+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/watcher-api-put-watch.html">
54+
* the docs</a> for more.
55+
* @param request the request
56+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
57+
* @param listener the listener to be notified upon request completion
58+
*/
59+
public void putWatchAsync(PutWatchRequest request, RequestOptions options,
60+
ActionListener<PutWatchResponse> listener) {
61+
restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::xPackWatcherPutWatch, options,
62+
PutWatchResponse::fromXContent, listener, emptySet());
63+
}
64+
}

client/rest-high-level/src/main/java/org/elasticsearch/client/XPackClient.java

+7
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,17 @@
3939
* X-Pack APIs on elastic.co</a> for more information.
4040
*/
4141
public final class XPackClient {
42+
4243
private final RestHighLevelClient restHighLevelClient;
44+
private final WatcherClient watcherClient;
4345

4446
XPackClient(RestHighLevelClient restHighLevelClient) {
4547
this.restHighLevelClient = restHighLevelClient;
48+
this.watcherClient = new WatcherClient(restHighLevelClient);
49+
}
50+
51+
public WatcherClient watcher() {
52+
return watcherClient;
4653
}
4754

4855
/**

client/rest-high-level/src/test/java/org/elasticsearch/client/PingAndInfoIT.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ public void testXPackInfo() throws IOException {
6666

6767
assertEquals(mainResponse.getBuild().shortHash(), info.getBuildInfo().getHash());
6868

69-
assertEquals("basic", info.getLicenseInfo().getType());
70-
assertEquals("basic", info.getLicenseInfo().getMode());
69+
assertEquals("trial", info.getLicenseInfo().getType());
70+
assertEquals("trial", info.getLicenseInfo().getMode());
7171
assertEquals(LicenseStatus.ACTIVE, info.getLicenseInfo().getStatus());
7272

7373
FeatureSet graph = info.getFeatureSetsInfo().getFeatureSets().get("graph");
7474
assertNotNull(graph.description());
75-
assertFalse(graph.available());
75+
assertTrue(graph.available());
7676
assertTrue(graph.enabled());
7777
assertNull(graph.nativeCodeInfo());
7878
FeatureSet monitoring = info.getFeatureSetsInfo().getFeatureSets().get("monitoring");
@@ -82,7 +82,7 @@ public void testXPackInfo() throws IOException {
8282
assertNull(monitoring.nativeCodeInfo());
8383
FeatureSet ml = info.getFeatureSetsInfo().getFeatureSets().get("ml");
8484
assertNotNull(ml.description());
85-
assertFalse(ml.available());
85+
assertTrue(ml.available());
8686
assertTrue(ml.enabled());
8787
assertEquals(mainResponse.getVersion().toString(),
8888
ml.nativeCodeInfo().get("version").toString().replace("-SNAPSHOT", ""));

client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java

+32
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
4242
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
4343
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
44+
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
4445
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
4546
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
4647
import org.elasticsearch.action.admin.indices.alias.Alias;
@@ -124,6 +125,7 @@
124125
import org.elasticsearch.index.rankeval.RatedRequest;
125126
import org.elasticsearch.index.rankeval.RestRankEvalAction;
126127
import org.elasticsearch.protocol.xpack.XPackInfoRequest;
128+
import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
127129
import org.elasticsearch.repositories.fs.FsRepository;
128130
import org.elasticsearch.rest.action.search.RestSearchAction;
129131
import org.elasticsearch.script.ScriptType;
@@ -144,6 +146,7 @@
144146
import org.elasticsearch.test.RandomObjects;
145147
import org.hamcrest.CoreMatchers;
146148

149+
import java.io.ByteArrayOutputStream;
147150
import java.io.IOException;
148151
import java.io.InputStream;
149152
import java.nio.charset.StandardCharsets;
@@ -2531,6 +2534,35 @@ public void testXPackInfo() {
25312534
assertEquals(expectedParams, request.getParameters());
25322535
}
25332536

2537+
public void testXPackPutWatch() throws Exception {
2538+
PutWatchRequest putWatchRequest = new PutWatchRequest();
2539+
String watchId = randomAlphaOfLength(10);
2540+
putWatchRequest.setId(watchId);
2541+
String body = randomAlphaOfLength(20);
2542+
putWatchRequest.setSource(new BytesArray(body), XContentType.JSON);
2543+
2544+
Map<String, String> expectedParams = new HashMap<>();
2545+
if (randomBoolean()) {
2546+
putWatchRequest.setActive(false);
2547+
expectedParams.put("active", "false");
2548+
}
2549+
2550+
if (randomBoolean()) {
2551+
long version = randomLongBetween(10, 100);
2552+
putWatchRequest.setVersion(version);
2553+
expectedParams.put("version", String.valueOf(version));
2554+
}
2555+
2556+
Request request = RequestConverters.xPackWatcherPutWatch(putWatchRequest);
2557+
assertEquals(HttpPut.METHOD_NAME, request.getMethod());
2558+
assertEquals("/_xpack/watcher/watch/" + watchId, request.getEndpoint());
2559+
assertEquals(expectedParams, request.getParameters());
2560+
assertThat(request.getEntity().getContentType().getValue(), is(XContentType.JSON.mediaTypeWithoutParameters()));
2561+
ByteArrayOutputStream bos = new ByteArrayOutputStream();
2562+
request.getEntity().writeTo(bos);
2563+
assertThat(bos.toString("UTF-8"), is(body));
2564+
}
2565+
25342566
/**
25352567
* Randomize the {@link FetchSourceContext} request parameters.
25362568
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.elasticsearch.client;
20+
21+
import org.elasticsearch.common.bytes.BytesArray;
22+
import org.elasticsearch.common.bytes.BytesReference;
23+
import org.elasticsearch.common.xcontent.XContentType;
24+
import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
25+
import org.elasticsearch.protocol.xpack.watcher.PutWatchResponse;
26+
27+
import static org.hamcrest.Matchers.is;
28+
29+
public class WatcherIT extends ESRestHighLevelClientTestCase {
30+
31+
public void testPutWatch() throws Exception {
32+
String watchId = randomAlphaOfLength(10);
33+
String json = "{ \n" +
34+
" \"trigger\": { \"schedule\": { \"interval\": \"10h\" } },\n" +
35+
" \"input\": { \"none\": {} },\n" +
36+
" \"actions\": { \"logme\": { \"logging\": { \"text\": \"{{ctx.payload}}\" } } }\n" +
37+
"}";
38+
BytesReference bytesReference = new BytesArray(json);
39+
PutWatchRequest putWatchRequest = new PutWatchRequest(watchId, bytesReference, XContentType.JSON);
40+
PutWatchResponse putWatchResponse = highLevelClient().xpack().watcher().putWatch(putWatchRequest, RequestOptions.DEFAULT);
41+
assertThat(putWatchResponse.isCreated(), is(true));
42+
assertThat(putWatchResponse.getId(), is(watchId));
43+
assertThat(putWatchResponse.getVersion(), is(1L));
44+
}
45+
46+
}

client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MiscellaneousDocumentationIT.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,13 @@
3939
import org.elasticsearch.protocol.xpack.XPackUsageResponse;
4040

4141
import java.io.IOException;
42+
import java.time.Instant;
4243
import java.util.EnumSet;
4344
import java.util.Map;
4445
import java.util.concurrent.CountDownLatch;
4546
import java.util.concurrent.TimeUnit;
4647

48+
import static org.hamcrest.Matchers.greaterThan;
4749
import static org.hamcrest.Matchers.is;
4850

4951
/**
@@ -98,8 +100,7 @@ public void testXPackInfo() throws Exception {
98100
//tag::x-pack-info-response
99101
BuildInfo build = response.getBuildInfo(); // <1>
100102
LicenseInfo license = response.getLicenseInfo(); // <2>
101-
assertEquals(XPackInfoResponse.BASIC_SELF_GENERATED_LICENSE_EXPIRATION_MILLIS,
102-
license.getExpiryDate()); // <3>
103+
assertThat(license.getExpiryDate(), is(greaterThan(Instant.now().toEpochMilli()))); // <3>
103104
FeatureSetsInfo features = response.getFeatureSetsInfo(); // <4>
104105
//end::x-pack-info-response
105106

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.elasticsearch.client.documentation;
20+
21+
import org.elasticsearch.action.ActionListener;
22+
import org.elasticsearch.action.LatchedActionListener;
23+
import org.elasticsearch.client.ESRestHighLevelClientTestCase;
24+
import org.elasticsearch.client.RequestOptions;
25+
import org.elasticsearch.client.RestHighLevelClient;
26+
import org.elasticsearch.common.bytes.BytesArray;
27+
import org.elasticsearch.common.bytes.BytesReference;
28+
import org.elasticsearch.common.xcontent.XContentType;
29+
import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
30+
import org.elasticsearch.protocol.xpack.watcher.PutWatchResponse;
31+
32+
import java.util.concurrent.CountDownLatch;
33+
import java.util.concurrent.TimeUnit;
34+
35+
public class WatcherDocumentationIT extends ESRestHighLevelClientTestCase {
36+
37+
public void testPutWatch() throws Exception {
38+
RestHighLevelClient client = highLevelClient();
39+
40+
{
41+
//tag::x-pack-put-watch-execute
42+
// you can also use the WatchSourceBuilder from org.elasticsearch.plugin:x-pack-core to create a watch programmatically
43+
BytesReference watch = new BytesArray("{ \n" +
44+
" \"trigger\": { \"schedule\": { \"interval\": \"10h\" } },\n" +
45+
" \"input\": { \"simple\": { \"foo\" : \"bar\" } },\n" +
46+
" \"actions\": { \"logme\": { \"logging\": { \"text\": \"{{ctx.payload}}\" } } }\n" +
47+
"}");
48+
PutWatchRequest request = new PutWatchRequest("my_watch_id", watch, XContentType.JSON);
49+
request.setActive(false); // <1>
50+
PutWatchResponse response = client.xpack().watcher().putWatch(request, RequestOptions.DEFAULT);
51+
//end::x-pack-put-watch-execute
52+
53+
//tag::x-pack-put-watch-response
54+
String watchId = response.getId(); // <1>
55+
boolean isCreated = response.isCreated(); // <2>
56+
long version = response.getVersion(); // <3>
57+
//end::x-pack-put-watch-response
58+
}
59+
60+
{
61+
BytesReference watch = new BytesArray("{ \n" +
62+
" \"trigger\": { \"schedule\": { \"interval\": \"10h\" } },\n" +
63+
" \"input\": { \"simple\": { \"foo\" : \"bar\" } },\n" +
64+
" \"actions\": { \"logme\": { \"logging\": { \"text\": \"{{ctx.payload}}\" } } }\n" +
65+
"}");
66+
PutWatchRequest request = new PutWatchRequest("my_other_watch_id", watch, XContentType.JSON);
67+
// tag::x-pack-put-watch-execute-listener
68+
ActionListener<PutWatchResponse> listener = new ActionListener<PutWatchResponse>() {
69+
@Override
70+
public void onResponse(PutWatchResponse response) {
71+
// <1>
72+
}
73+
74+
@Override
75+
public void onFailure(Exception e) {
76+
// <2>
77+
}
78+
};
79+
// end::x-pack-put-watch-execute-listener
80+
81+
// Replace the empty listener by a blocking listener in test
82+
final CountDownLatch latch = new CountDownLatch(1);
83+
listener = new LatchedActionListener<>(listener, latch);
84+
85+
// tag::x-pack-put-watch-execute-async
86+
client.xpack().watcher().putWatchAsync(request, RequestOptions.DEFAULT, listener); // <1>
87+
// end::x-pack-put-watch-execute-async
88+
89+
assertTrue(latch.await(30L, TimeUnit.SECONDS));
90+
}
91+
}
92+
}

docs/java-rest/high-level/supported-apis.asciidoc

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ The Java High Level REST Client supports the following Miscellaneous APIs:
5757

5858
include::miscellaneous/main.asciidoc[]
5959
include::miscellaneous/ping.asciidoc[]
60-
include::miscellaneous/x-pack-info.asciidoc[]
60+
include::x-pack/x-pack-info.asciidoc[]
61+
include::x-pack/watcher/put-watch.asciidoc[]
6162

6263
== Indices APIs
6364

0 commit comments

Comments
 (0)