diff --git a/plugin/src/test/java/org/elasticsearch/xpack/watcher/input/http/HttpInputIntegrationTests.java b/plugin/src/test/java/org/elasticsearch/xpack/watcher/input/http/HttpInputIntegrationTests.java deleted file mode 100644 index c889d9975d9..00000000000 --- a/plugin/src/test/java/org/elasticsearch/xpack/watcher/input/http/HttpInputIntegrationTests.java +++ /dev/null @@ -1,147 +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.xpack.watcher.input.http; - -import org.elasticsearch.action.search.SearchResponse; -import org.elasticsearch.action.support.IndicesOptions; -import org.elasticsearch.common.network.NetworkModule; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.test.junit.annotations.TestLogging; -import org.elasticsearch.transport.Netty4Plugin; -import org.elasticsearch.xpack.watcher.client.WatcherClient; -import org.elasticsearch.xpack.watcher.common.http.HttpRequestTemplate; -import org.elasticsearch.xpack.watcher.common.text.TextTemplate; -import org.elasticsearch.xpack.watcher.condition.CompareCondition; -import org.elasticsearch.xpack.watcher.history.HistoryStore; -import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource; -import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase; -import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse; -import org.elasticsearch.xpack.watcher.trigger.schedule.IntervalSchedule; - -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.Collection; - -import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; -import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; -import static org.elasticsearch.index.query.QueryBuilders.matchQuery; -import static org.elasticsearch.index.query.QueryBuilders.termQuery; -import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; -import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.loggingAction; -import static org.elasticsearch.xpack.watcher.client.WatchSourceBuilders.watchBuilder; -import static org.elasticsearch.xpack.watcher.input.InputBuilders.httpInput; -import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.xContentSource; -import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule; -import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.interval; -import static org.hamcrest.Matchers.equalTo; - -@TestLogging("org.elasticsearch.xpack.watcher:DEBUG,org.elasticsearch.xpack.watcher.WatcherIndexingListener:TRACE") -public class HttpInputIntegrationTests extends AbstractWatcherIntegrationTestCase { - - @Override - protected Settings nodeSettings(int nodeOrdinal) { - return Settings.builder() - .put(super.nodeSettings(nodeOrdinal)) - .put(NetworkModule.HTTP_ENABLED.getKey(), true) - .build(); - } - - @Override - protected Collection> nodePlugins() { - ArrayList> plugins = new ArrayList<>(super.nodePlugins()); - plugins.add(Netty4Plugin.class); // for http - return plugins; - } - - public void testHttpInput() throws Exception { - createIndex("index"); - client().prepareIndex("index", "type", "id").setSource("{}", XContentType.JSON).setRefreshPolicy(IMMEDIATE).get(); - - InetSocketAddress address = internalCluster().httpAddresses()[0]; - watcherClient().preparePutWatch("_name") - .setSource(watchBuilder() - .trigger(schedule(interval("5s"))) - .input(httpInput(HttpRequestTemplate.builder(address.getHostString(), address.getPort()) - .path("/index/_search") - .body(jsonBuilder().startObject().field("size", 1).endObject().string()) - .putHeader("Content-Type", new TextTemplate("application/json")))) - .condition(new CompareCondition("ctx.payload.hits.total", CompareCondition.Op.EQ, 1L)) - .addAction("_id", loggingAction("anything"))) - .get(); - - timeWarp().trigger("_name"); - refresh(); - assertWatchWithMinimumPerformedActionsCount("_name", 1, false); - } - - public void testHttpInputClusterStats() throws Exception { - InetSocketAddress address = internalCluster().httpAddresses()[0]; - PutWatchResponse putWatchResponse = watcherClient().preparePutWatch("_name") - .setSource(watchBuilder() - .trigger(schedule(interval("1s"))) - .input(httpInput(HttpRequestTemplate.builder(address.getHostString(), address.getPort()).path("/_cluster/stats"))) - .condition(new CompareCondition("ctx.payload.nodes.count.total", CompareCondition.Op.GTE, 1L)) - .addAction("_id", loggingAction("anything"))) - .get(); - - assertTrue(putWatchResponse.isCreated()); - timeWarp().trigger("_name"); - refresh(); - assertWatchWithMinimumPerformedActionsCount("_name", 1, false); - } - - public void testInputFiltering() throws Exception { - WatcherClient watcherClient = watcherClient(); - createIndex("idx"); - // Have a sample document in the index, the watch is going to evaluate - client().prepareIndex("idx", "type").setSource("field", "value").get(); - refresh(); - - InetSocketAddress address = internalCluster().httpAddresses()[0]; - XContentBuilder body = jsonBuilder().prettyPrint().startObject() - .field("query").value(termQuery("field", "value")) - .endObject(); - HttpRequestTemplate.Builder requestBuilder = HttpRequestTemplate.builder(address.getHostString(), address.getPort()) - .path(new TextTemplate("/idx/_search")) - .body(body.string()); - - watcherClient.preparePutWatch("_name1") - .setSource(watchBuilder() - .trigger(schedule(interval(10, IntervalSchedule.Interval.Unit.SECONDS))) - .input(httpInput(requestBuilder).extractKeys("hits.total")) - .condition(new CompareCondition("ctx.payload.hits.total", CompareCondition.Op.EQ, 1L))) - .get(); - - // in this watcher the condition will fail, because max_score isn't extracted, only total: - watcherClient.preparePutWatch("_name2") - .setSource(watchBuilder() - .trigger(schedule(interval(10, IntervalSchedule.Interval.Unit.SECONDS))) - .input(httpInput(requestBuilder).extractKeys("hits.total")) - .condition(new CompareCondition("ctx.payload.hits.max_score", CompareCondition.Op.GTE, 0L))) - .get(); - - timeWarp().trigger("_name1"); - timeWarp().trigger("_name2"); - refresh(); - - assertWatchWithMinimumPerformedActionsCount("_name1", 1, false); - assertWatchWithNoActionNeeded("_name2", 1); - - // Check that the input result payload has been filtered - refresh(); - SearchResponse searchResponse = client().prepareSearch(HistoryStore.INDEX_PREFIX_WITH_TEMPLATE + "*") - .setIndicesOptions(IndicesOptions.lenientExpandOpen()) - .setQuery(matchQuery("watch_id", "_name1")) - .setSize(1) - .get(); - assertHitCount(searchResponse, 1); - XContentSource source = xContentSource(searchResponse.getHits().getAt(0).getSourceRef()); - assertThat(source.getValue("result.input.payload.hits.total"), equalTo((Object) 1)); - } -} diff --git a/plugin/src/test/java/org/elasticsearch/xpack/watcher/input/http/HttpInputTests.java b/plugin/src/test/java/org/elasticsearch/xpack/watcher/input/http/HttpInputTests.java index 88da927ed66..51742863b05 100644 --- a/plugin/src/test/java/org/elasticsearch/xpack/watcher/input/http/HttpInputTests.java +++ b/plugin/src/test/java/org/elasticsearch/xpack/watcher/input/http/HttpInputTests.java @@ -220,12 +220,9 @@ public class HttpInputTests extends ESTestCase { .endObject(); XContentParser parser = createParser(builder); parser.nextToken(); - try { - httpParser.parseInput("_id", parser); - fail("Expected IllegalArgumentException"); - } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), is("unsupported http method [_METHOD]")); - } + + IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> httpParser.parseInput("_id", parser)); + assertThat(e.getMessage(), is("unsupported http method [_METHOD]")); } public void testThatHeadersAreIncludedInPayload() throws Exception { diff --git a/plugin/src/test/resources/rest-api-spec/test/watcher/execute_watch/60_http_input.yml b/plugin/src/test/resources/rest-api-spec/test/watcher/execute_watch/60_http_input.yml new file mode 100644 index 00000000000..8a9ba14cb84 --- /dev/null +++ b/plugin/src/test/resources/rest-api-spec/test/watcher/execute_watch/60_http_input.yml @@ -0,0 +1,58 @@ +--- +setup: + - do: + cluster.health: + wait_for_status: yellow + +--- +"HTTP input supports extracting of keys": + + - do: + cluster.state: {} + - set: { metadata.cluster_uuid : cluster_uuid } + - set: { master_node: master } + + - do: + nodes.info: {} + - set: { nodes.$master.http.publish_address: http_host } + + - do: + xpack.watcher.execute_watch: + body: > + { + "watch" : { + "trigger": { + "schedule": { + "interval": "1s" + } + }, + "input" : { + "http": { + "request": { + "url": "http://${http_host}/_cluster/health", + "auth" : { + "basic" : { + "username" : "x_pack_rest_user", + "password" : "x-pack-test-password" + } + } + }, + "extract": [ "timed_out", "cluster_name" ] + } + }, + "actions": { + "log": { + "logging": { + "text": "executed at {{ctx.execution_time}}" + } + } + } + } + } + + - match: { watch_record.result.input.payload.timed_out: false } + - match: { watch_record.result.input.payload._status_code: 200 } + - is_true: watch_record.result.input.payload._headers + - is_true: watch_record.result.input.payload.cluster_name + # not part of the extract keys, should not occur + - is_false: watch_record.result.input.payload.status diff --git a/qa/smoke-test-watcher-with-security/build.gradle b/qa/smoke-test-watcher-with-security/build.gradle index 36ce6681917..55280b4b791 100644 --- a/qa/smoke-test-watcher-with-security/build.gradle +++ b/qa/smoke-test-watcher-with-security/build.gradle @@ -32,6 +32,8 @@ integTestCluster { extraConfigFile 'x-pack/roles.yml', 'roles.yml' setupCommand 'setupTestAdminUser', 'bin/x-pack/users', 'useradd', 'test_admin', '-p', 'x-pack-test-password', '-r', 'superuser' + setupCommand 'setupXpackUserForTests', + 'bin/x-pack/users', 'useradd', 'x_pack_rest_user', '-p', 'x-pack-test-password', '-r', 'watcher_manager' setupCommand 'setupWatcherManagerUser', 'bin/x-pack/users', 'useradd', 'watcher_manager', '-p', 'x-pack-test-password', '-r', 'watcher_manager' setupCommand 'setupPowerlessUser',