org.graylog2.ElasticsearchBase.java Source code

Java tutorial

Introduction

Here is the source code for org.graylog2.ElasticsearchBase.java

Source

/**
 * This file is part of Graylog.
 *
 * Graylog is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Graylog is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Graylog.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.graylog2;

import com.fasterxml.jackson.databind.JsonNode;
import com.github.joschi.jadconfig.util.Duration;
import com.github.joschi.nosqlunit.elasticsearch.http.ElasticsearchConfiguration;
import com.github.joschi.nosqlunit.elasticsearch.http.ElasticsearchRule;
import com.github.zafarkhaja.semver.Version;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.Resources;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import io.searchbox.cluster.Health;
import io.searchbox.core.Ping;
import io.searchbox.indices.CloseIndex;
import io.searchbox.indices.CreateIndex;
import io.searchbox.indices.DeleteIndex;
import io.searchbox.indices.IndicesExists;
import io.searchbox.indices.aliases.AddAliasMapping;
import io.searchbox.indices.aliases.ModifyAliases;
import io.searchbox.indices.aliases.RemoveAliasMapping;
import io.searchbox.indices.mapping.GetMapping;
import io.searchbox.indices.template.DeleteTemplate;
import io.searchbox.indices.template.GetTemplate;
import io.searchbox.indices.template.PutTemplate;
import org.graylog2.indexer.IndexMapping;
import org.graylog2.indexer.IndexMapping5;
import org.junit.Rule;

import javax.inject.Inject;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

import static com.google.common.base.Strings.nullToEmpty;
import static org.assertj.core.api.Assertions.assertThat;

public abstract class ElasticsearchBase {
    private static final String PROPERTIES_RESOURCE_NAME = "elasticsearch.properties";
    private static final String DEFAULT_PORT = "9200";

    public static final Duration ES_TIMEOUT = Duration.seconds(5L);

    @Rule
    public final ElasticsearchRule elasticsearchRule;

    @Inject
    private JestClient jestClient;

    private final Properties properties;
    private final Version elasticsearchVersion;

    public ElasticsearchBase() {
        this.properties = loadProperties(PROPERTIES_RESOURCE_NAME);
        this.elasticsearchVersion = Version.valueOf(properties.getProperty("version"));
        this.elasticsearchRule = elasticsearchRule().build();
    }

    private Properties loadProperties(String resourceName) {
        final Properties properties = new Properties();
        final URL resource = Resources.getResource(resourceName);
        try (InputStream stream = resource.openStream()) {
            properties.load(stream);
        } catch (IOException e) {
            throw new UncheckedIOException("Error while reading test properties", e);
        }
        return properties;
    }

    protected String getHttpPort() {
        return properties.getProperty("httpPort", DEFAULT_PORT);
    }

    protected String getServer() {
        return "http://localhost:" + getHttpPort();
    }

    protected ElasticsearchConfiguration.Builder elasticsearchConfiguration() {
        return ElasticsearchConfiguration.remoteElasticsearch(getServer());
    }

    protected ElasticsearchRule.Builder elasticsearchRule() {
        final ElasticsearchConfiguration configuration = elasticsearchConfiguration().build();
        return ElasticsearchRule.newElasticsearchRule().configure(configuration);
    }

    protected JestClient client() {
        return jestClient;
    }

    protected void assertSucceeded(JestResult jestResult) {
        final String errorMessage = nullToEmpty(jestResult.getErrorMessage());
        assertThat(jestResult.isSucceeded()).overridingErrorMessage(errorMessage).isTrue();
    }

    protected IndexMapping indexMapping() {
        switch (elasticsearchVersion.getMajorVersion()) {
        case 5:
            return new IndexMapping5();
        default:
            throw new IllegalStateException("Only Elasticsearch 5.x is supported");
        }
    }

    public void createIndex(String index) throws IOException {
        createIndex(index, 1, 0);
    }

    public void createIndex(String index, int shards, int replicas) throws IOException {
        createIndex(index, shards, replicas, Collections.emptyMap());
    }

    public void createIndex(String index, int shards, int replicas, Map<String, Object> indexSettings)
            throws IOException {
        final Map<String, Object> settings = new HashMap<>();
        settings.put("number_of_shards", shards);
        settings.put("number_of_replicas", replicas);

        if (indexSettings.containsKey("settings")) {
            @SuppressWarnings("unchecked")
            final Map<String, Object> customSettings = (Map<String, Object>) indexSettings.get("settings");
            settings.putAll(customSettings);
        }

        final Map<String, Object> mappings = new HashMap<>();
        if (indexSettings.containsKey("mappings")) {
            @SuppressWarnings("unchecked")
            final Map<String, Object> customMappings = (Map<String, Object>) indexSettings.get("mappings");
            mappings.putAll(customMappings);
        }

        final ImmutableMap<String, Map<String, Object>> finalSettings = ImmutableMap.of("settings", settings,
                "mappings", mappings);
        final CreateIndex createIndex = new CreateIndex.Builder(index).settings(finalSettings).build();
        final JestResult createIndexResponse = client().execute(createIndex);

        assertSucceeded(createIndexResponse);
    }

    protected String createRandomIndex(String prefix) throws IOException {
        final String indexName = prefix + System.nanoTime();

        createIndex(indexName);
        waitForGreenStatus(indexName);

        return indexName;
    }

    public void deleteIndex(String... indices) throws IOException {
        for (String index : indices)
            if (indicesExists(index)) {
                final DeleteIndex deleteIndex = new DeleteIndex.Builder(index).build();
                final JestResult deleteIndexResponse = client().execute(deleteIndex);

                assertSucceeded(deleteIndexResponse);
            }
    }

    protected void closeIndex(String index) throws IOException {
        final CloseIndex closeIndex = new CloseIndex.Builder(index).build();
        final JestResult closeIndexResponse = client().execute(closeIndex);
        assertSucceeded(closeIndexResponse);
    }

    public boolean indicesExists(String... indices) throws IOException {
        final IndicesExists indicesExists = new IndicesExists.Builder(Arrays.asList(indices)).build();
        final JestResult indicesExistsResponse = client().execute(indicesExists);

        return indicesExistsResponse.isSucceeded();
    }

    protected void putTemplate(String templateName, Object source) throws IOException {
        final PutTemplate templateRequest = new PutTemplate.Builder(templateName, source).build();
        final JestResult templateResponse = client().execute(templateRequest);
        assertSucceeded(templateResponse);
    }

    protected void deleteTemplate(String templateName) throws IOException {
        final DeleteTemplate templateRequest = new DeleteTemplate.Builder(templateName).build();
        final JestResult templateResponse = client().execute(templateRequest);
        assertSucceeded(templateResponse);
    }

    protected JsonNode getTemplate(String templateName) throws IOException {
        final GetTemplate templateRequest = new GetTemplate.Builder(templateName).build();
        final JestResult templateResponse = client().execute(templateRequest);
        assertSucceeded(templateResponse);

        return templateResponse.getJsonObject();
    }

    protected JsonNode getTemplates() throws IOException {
        final GetTemplate templateRequest = new GetTemplate.Builder("").build();
        final JestResult templateResponse = client().execute(templateRequest);
        assertSucceeded(templateResponse);

        return templateResponse.getJsonObject();
    }

    protected JsonNode getMapping(String... indices) throws IOException {
        final GetMapping getMapping = new GetMapping.Builder().addIndex(Arrays.asList(indices)).build();
        final JestResult mappingResponse = client().execute(getMapping);
        assertSucceeded(mappingResponse);

        return mappingResponse.getJsonObject();
    }

    protected void addAliasMapping(String indexName, String alias) throws IOException {
        final AddAliasMapping addAliasMapping = new AddAliasMapping.Builder(indexName, alias).build();
        final ModifyAliases addAliasRequest = new ModifyAliases.Builder(addAliasMapping).build();
        final JestResult addAliasResponse = client().execute(addAliasRequest);
        assertSucceeded(addAliasResponse);
    }

    protected void removeAliasMapping(String indexName, String alias) throws IOException {
        final RemoveAliasMapping removeAliasMapping = new RemoveAliasMapping.Builder(indexName, alias).build();
        final ModifyAliases removeAliasRequest = new ModifyAliases.Builder(removeAliasMapping).build();
        final JestResult removeAliasResponse = client().execute(removeAliasRequest);
        assertSucceeded(removeAliasResponse);
    }

    public void waitForGreenStatus(String... indices) throws IOException {
        waitForStatus(Health.Status.GREEN, indices);
    }

    public Health.Status waitForStatus(Health.Status status, String... indices) throws IOException {
        final Health health = new Health.Builder().addIndex(Arrays.asList(indices)).waitForStatus(status)
                .timeout((int) ES_TIMEOUT.toSeconds()).build();

        final JestResult clusterHealthResponse = client().execute(health);
        assertSucceeded(clusterHealthResponse);

        final String actualStatus = clusterHealthResponse.getJsonObject().get("status").asText();
        assertThat(actualStatus).isNotBlank().isEqualTo(status.getKey());

        return Health.Status.valueOf(actualStatus.toUpperCase(Locale.ROOT));
    }

    public Version remoteElasticsearchVersion() throws IOException {
        final Ping ping = new Ping.Builder().build();
        final JestResult pingResponse = client().execute(ping);
        assertSucceeded(pingResponse);

        return Version.valueOf(pingResponse.getJsonObject().path("version").path("number").asText());
    }

    public Version getElasticsearchVersion() throws IOException {
        return elasticsearchVersion;
    }

}