org.elasticsearch.smoketest.SmokeTestWatcherTestSuiteIT.java Source code

Java tutorial

Introduction

Here is the source code for org.elasticsearch.smoketest.SmokeTestWatcherTestSuiteIT.java

Source

/*
 * 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.smoketest;

import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.elasticsearch.client.Response;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.test.rest.ESRestTestCase;
import org.elasticsearch.test.rest.yaml.ObjectPath;
import org.elasticsearch.xpack.core.watcher.support.WatcherIndexTemplateRegistryField;
import org.junit.After;
import org.junit.Before;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

import static java.util.Collections.emptyMap;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;

public class SmokeTestWatcherTestSuiteIT extends ESRestTestCase {

    private static final String TEST_ADMIN_USERNAME = "test_admin";
    private static final String TEST_ADMIN_PASSWORD = "x-pack-test-password";

    @Before
    public void startWatcher() throws Exception {
        // delete the watcher history to not clutter with entries from other test
        assertOK(adminClient().performRequest("DELETE", ".watcher-history-*"));

        assertBusy(() -> {
            Response response = adminClient().performRequest("GET", "_xpack/watcher/stats");
            String state = ObjectPath.createFromResponse(response).evaluate("stats.0.watcher_state");

            switch (state) {
            case "stopped":
                Response startResponse = adminClient().performRequest("POST", "/_xpack/watcher/_start");
                boolean isAcknowledged = ObjectPath.createFromResponse(startResponse).evaluate("acknowledged");
                assertThat(isAcknowledged, is(true));
                break;
            case "stopping":
                throw new AssertionError("waiting until stopping state reached stopped state to start again");
            case "starting":
                throw new AssertionError("waiting until starting state reached started state");
            case "started":
                // all good here, we are done
                break;
            default:
                throw new AssertionError("unknown state[" + state + "]");
            }
        });

        assertBusy(() -> {
            for (String template : WatcherIndexTemplateRegistryField.TEMPLATE_NAMES) {
                Response templateExistsResponse = adminClient().performRequest("HEAD", "_template/" + template,
                        emptyMap());
                assertThat(templateExistsResponse.getStatusLine().getStatusCode(), is(200));
            }
        });
    }

    @After
    public void stopWatcher() throws Exception {
        assertBusy(() -> {
            Response response = adminClient().performRequest("GET", "_xpack/watcher/stats", emptyMap());
            String state = ObjectPath.createFromResponse(response).evaluate("stats.0.watcher_state");

            switch (state) {
            case "stopped":
                // all good here, we are done
                break;
            case "stopping":
                throw new AssertionError("waiting until stopping state reached stopped state");
            case "starting":
                throw new AssertionError("waiting until starting state reached started state to stop");
            case "started":
                Response stopResponse = adminClient().performRequest("POST", "/_xpack/watcher/_stop", emptyMap());
                boolean isAcknowledged = ObjectPath.createFromResponse(stopResponse).evaluate("acknowledged");
                assertThat(isAcknowledged, is(true));
                break;
            default:
                throw new AssertionError("unknown state[" + state + "]");
            }
        });
    }

    @Override
    protected Settings restClientSettings() {
        String token = basicAuthHeaderValue("watcher_manager",
                new SecureString("x-pack-test-password".toCharArray()));
        return Settings.builder().put(ThreadContext.PREFIX + ".Authorization", token).build();
    }

    @Override
    protected Settings restAdminSettings() {
        String token = basicAuthHeaderValue(TEST_ADMIN_USERNAME,
                new SecureString(TEST_ADMIN_PASSWORD.toCharArray()));
        return Settings.builder().put(ThreadContext.PREFIX + ".Authorization", token).build();
    }

    public void testMonitorClusterHealth() throws Exception {
        String watchId = "cluster_health_watch";

        // get master publish address
        Response clusterStateResponse = adminClient().performRequest("GET", "_cluster/state");
        ObjectPath clusterState = ObjectPath.createFromResponse(clusterStateResponse);
        String masterNode = clusterState.evaluate("master_node");
        assertThat(masterNode, is(notNullValue()));

        Response statsResponse = adminClient().performRequest("GET", "_nodes");
        ObjectPath stats = ObjectPath.createFromResponse(statsResponse);
        String address = stats.evaluate("nodes." + masterNode + ".http.publish_address");
        assertThat(address, is(notNullValue()));
        String[] splitAddress = address.split(":", 2);
        String host = splitAddress[0];
        int port = Integer.valueOf(splitAddress[1]);

        // put watch
        try (XContentBuilder builder = jsonBuilder()) {
            builder.startObject();
            // trigger
            builder.startObject("trigger").startObject("schedule").field("interval", "1s").endObject().endObject();
            // input
            builder.startObject("input").startObject("http").startObject("request").field("host", host)
                    .field("port", port).field("path", "/_cluster/health").field("scheme", "http")
                    .startObject("auth").startObject("basic").field("username", TEST_ADMIN_USERNAME)
                    .field("password", TEST_ADMIN_PASSWORD).endObject().endObject().endObject().endObject()
                    .endObject();
            // condition
            builder.startObject("condition").startObject("compare").startObject("ctx.payload.number_of_data_nodes")
                    .field("lt", 10).endObject().endObject().endObject();
            // actions
            builder.startObject("actions").startObject("log").startObject("logging").field("text", "executed")
                    .endObject().endObject().endObject();

            builder.endObject();

            indexWatch(watchId, builder);
        }

        // check watch count
        assertWatchCount(1);

        // check watch history
        ObjectPath objectPath = getWatchHistoryEntry(watchId);
        boolean conditionMet = objectPath.evaluate("hits.hits.0._source.result.condition.met");
        assertThat(conditionMet, is(true));

        deleteWatch(watchId);
        assertWatchCount(0);
    }

    private void indexWatch(String watchId, XContentBuilder builder) throws Exception {
        StringEntity entity = new StringEntity(Strings.toString(builder), ContentType.APPLICATION_JSON);

        Response response = client().performRequest("PUT", "_xpack/watcher/watch/" + watchId, emptyMap(), entity);
        assertOK(response);
        Map<String, Object> responseMap = entityAsMap(response);
        assertThat(responseMap, hasEntry("_id", watchId));
    }

    private void deleteWatch(String watchId) throws IOException {
        Response response = client().performRequest("DELETE", "_xpack/watcher/watch/" + watchId);
        assertOK(response);
        ObjectPath path = ObjectPath.createFromResponse(response);
        boolean found = path.evaluate("found");
        assertThat(found, is(true));
    }

    private ObjectPath getWatchHistoryEntry(String watchId) throws Exception {
        final AtomicReference<ObjectPath> objectPathReference = new AtomicReference<>();
        assertBusy(() -> {
            client().performRequest("POST", ".watcher-history-*/_refresh");

            try (XContentBuilder builder = jsonBuilder()) {
                builder.startObject();
                builder.startObject("query").startObject("bool").startArray("must");
                builder.startObject().startObject("term").startObject("watch_id").field("value", watchId)
                        .endObject().endObject().endObject();
                builder.endArray().endObject().endObject();
                builder.startArray("sort").startObject().startObject("trigger_event.triggered_time")
                        .field("order", "desc").endObject().endObject().endArray();
                builder.endObject();

                StringEntity entity = new StringEntity(Strings.toString(builder), ContentType.APPLICATION_JSON);
                Response response = client().performRequest("POST", ".watcher-history-*/_search", emptyMap(),
                        entity);
                ObjectPath objectPath = ObjectPath.createFromResponse(response);
                int totalHits = objectPath.evaluate("hits.total");
                assertThat(totalHits, is(greaterThanOrEqualTo(1)));
                String watchid = objectPath.evaluate("hits.hits.0._source.watch_id");
                assertThat(watchid, is(watchId));
                objectPathReference.set(objectPath);
            }
        });
        return objectPathReference.get();
    }

    private void assertWatchCount(int expectedWatches) throws IOException {
        Response watcherStatsResponse = adminClient().performRequest("GET", "_xpack/watcher/stats");
        ObjectPath objectPath = ObjectPath.createFromResponse(watcherStatsResponse);
        int watchCount = objectPath.evaluate("stats.0.watch_count");
        assertThat(watchCount, is(expectedWatches));
    }
}