org.elasticsearch.multi_node.GlobalCheckpointSyncActionIT.java Source code

Java tutorial

Introduction

Here is the source code for org.elasticsearch.multi_node.GlobalCheckpointSyncActionIT.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.multi_node;

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 java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
import static org.hamcrest.Matchers.equalTo;

public class GlobalCheckpointSyncActionIT extends ESRestTestCase {

    @Override
    protected Settings restClientSettings() {
        return getClientSettings("test-user", "x-pack-test-password");
    }

    @Override
    protected Settings restAdminSettings() {
        return getClientSettings("super-user", "x-pack-super-password");
    }

    private Settings getClientSettings(final String username, final String password) {
        final String token = basicAuthHeaderValue(username, new SecureString(password.toCharArray()));
        return Settings.builder().put(ThreadContext.PREFIX + ".Authorization", token).build();
    }

    /*
     * The post-operation global checkpoint sync runs privileged as the system user otherwise the sync would be denied to restricted users.
     * This test ensures that these post-operation syncs are successful otherwise the global checkpoint would not have advanced on the
     * replica.
     */
    public void testGlobalCheckpointSyncActionRunsAsPrivilegedUser() throws Exception {
        // create the test-index index
        try (XContentBuilder builder = jsonBuilder()) {
            builder.startObject();
            {
                builder.startObject("settings");
                {
                    builder.field("index.number_of_shards", 1);
                    builder.field("index.number_of_replicas", 1);
                }
                builder.endObject();
            }
            builder.endObject();
            final StringEntity entity = new StringEntity(Strings.toString(builder), ContentType.APPLICATION_JSON);
            client().performRequest("PUT", "test-index", Collections.emptyMap(), entity);
        }

        // wait for the replica to recover
        client().performRequest("GET", "/_cluster/health", Collections.singletonMap("wait_for_status", "green"));

        // index some documents
        final int numberOfDocuments = randomIntBetween(0, 128);
        for (int i = 0; i < numberOfDocuments; i++) {
            try (XContentBuilder builder = jsonBuilder()) {
                builder.startObject();
                {
                    builder.field("foo", i);
                }
                builder.endObject();
                final StringEntity entity = new StringEntity(Strings.toString(builder),
                        ContentType.APPLICATION_JSON);
                client().performRequest("PUT", "/test-index/test-type/" + i, Collections.emptyMap(), entity);
            }
        }

        // we have to wait for the post-operation global checkpoint sync to propagate to the replica
        assertBusy(() -> {
            final Map<String, String> params = new HashMap<>(2);
            params.put("level", "shards");
            params.put("filter_path", "**.seq_no");
            final Response response = client().performRequest("GET", "/test-index/_stats", params);
            final ObjectPath path = ObjectPath.createFromResponse(response);
            // int looks funny here since global checkpoints are longs but the response parser does not know enough to treat them as long
            final int shard0GlobalCheckpoint = path
                    .evaluate("indices.test-index.shards.0.0.seq_no.global_checkpoint");
            assertThat(shard0GlobalCheckpoint, equalTo(numberOfDocuments - 1));
            final int shard1GlobalCheckpoint = path
                    .evaluate("indices.test-index.shards.0.1.seq_no.global_checkpoint");
            assertThat(shard1GlobalCheckpoint, equalTo(numberOfDocuments - 1));
        });
    }

}