Package org.elasticsearch.flume

Source Code of org.elasticsearch.flume.ElasticSearchSinkTest

package org.elasticsearch.flume;

import static org.elasticsearch.client.Requests.refreshRequest;
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
import static org.elasticsearch.index.query.QueryBuilders.fieldQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.queryString;
import static org.elasticsearch.node.NodeBuilder.nodeBuilder;
import static org.junit.Assert.assertEquals;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.gateway.Gateway;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.node.Node;
import org.elasticsearch.node.internal.InternalNode;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.cloudera.flume.core.Event;
import com.cloudera.flume.core.Event.Priority;
import com.cloudera.flume.core.EventImpl;
import com.cloudera.flume.core.EventSink;
import com.cloudera.flume.reporter.ReportEvent;

public class ElasticSearchSinkTest {

    private Node searchNode;

    private Client searchClient;
    private static final String INDEX_TYPE = "testIndexType";
    private static final String INDEX_NAME = "flume";

    @Before
    public void startSearchNode() throws Exception {
        Settings settings = settingsBuilder()
                .put("gateway.type", "none")
                .put("node.local", "true")
                .put("http.enabled", false)
                .put("index.store.type", "memory")
                .put("index.number_of_shards", "1")
                .put("index.number_of_replicas", "1")
                .build();

        searchNode = nodeBuilder()
                .settings(settings)
                .node();

        searchClient = searchNode.client();

        searchClient.admin()
                .cluster()
                .prepareHealth()
                .setWaitForGreenStatus()
                .execute()
                .actionGet();
    }

    @After
    public void stopSearchNode() throws Exception {
        // Reset the index
        ((InternalNode) searchNode).injector().getInstance(Gateway.class).reset();

        searchClient.close();
        searchNode.stop();
    }

    @Test
    public void appendDifferentTypesOfLogMessage() throws IOException, InterruptedException {
        ElasticSearchSink sink = createAndOpenSink();
        Map<String, byte[]> attributes = new HashMap<String, byte[]>();
        attributes.put("attr1", new String("qux quux quuux").getBytes());
        attributes.put("attr2", new String("value2").getBytes());
        attributes.put("attr3", new String("{\"key\":\"value\"}").getBytes());

        Event event = new EventImpl("message goes here".getBytes(), 0, Priority.INFO, System.nanoTime(),
                "localhost", attributes);

        sink.append(event);
        sink.append(new EventImpl("bleh foo baz bar".getBytes(), 1, Priority.WARN, System.nanoTime(), "notlocalhost"));
        sink.append(new EventImpl("{\"key\":\"value\"}".getBytes(), 2, Priority.DEBUG, System.nanoTime(), "jsonbody"));
        sink.append(new EventImpl("{\"key\":\"value\",\"complex\":{\"subkey\":\"subvalue\"}}".getBytes(), 3, Priority.DEBUG,
                System.nanoTime(), "complexjsonbody"));

        sink.close();

        searchClient.admin().indices().refresh(refreshRequest(INDEX_NAME)).actionGet();

        assertBasicSearch(event);
        assertPrioritySearch(event);
        assertHostSearch(event);
        assertBodySearch(event);
        assertFieldsSearch(event);
        assertJsonBody(event);
        assertComplexJsonBody(event);
    }

    @Test
    public void validateErrorCount() throws IOException, InterruptedException {
        ElasticSearchSink sink = createAndOpenSink();

        EventImpl invalidJsonEvent1 = new EventImpl("{ \"not json\" : no".getBytes(), 1, Priority.DEBUG, System.nanoTime(),
                "notlocalhost");
        sink.append(invalidJsonEvent1);
        sink.close();

        ReportEvent event = sink.getMetrics();
        long noOfFailedEvents = event.getLongMetric("NO_OF_FAILED_EVENTS");
        assertEquals("1 event should ", noOfFailedEvents, 1L);
    }

    @Test
    public void validateSinkIndexTypeConfiguration() throws IOException, InterruptedException {
        EventSink sink = createAndOpenSink("", "log", "");

        EventImpl event = new EventImpl("new index message".getBytes(), 1, Priority.WARN, System.nanoTime(), "notlocalhost");
        sink.append(event);
        sink.close();

        assertSimpleTest(INDEX_NAME, "log", 1);
    }

    @Test
    public void validateIndexNamePatternUsed() throws IOException, InterruptedException {
        ElasticSearchSink sink = createAndOpenSink("", "log", "test_%Y-%m-%d");

        sink.append(new EventImpl("new index message".getBytes(), 0, Priority.WARN, System.nanoTime(), "notlocalhost"));
        sink.append(new EventImpl("new index message".getBytes(), TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS), Priority.WARN,
                System.nanoTime(), "notlocalhost"));
        sink.close();

        assertSimpleTest("test_1970-01-01", "log", 1);
        assertSimpleTest("test_1970-01-02", "log", 1);
        assertSimpleTest(INDEX_NAME, "log", 2);
    }

    private void assertSimpleTest(String indexName, String indexType, int hits) {
        searchClient.admin().indices().refresh(refreshRequest(indexName)).actionGet();
        SearchResponse response = searchClient.prepareSearch(indexName).setTypes(indexType)
                .setQuery(fieldQuery("message.text", "new")).execute().actionGet();
        assertEquals("There should have been " + hits + " search result for default index type", hits, response.getHits()
                .getTotalHits());
    }

    private ElasticSearchSink createAndOpenSink() throws IOException, InterruptedException {
        return createAndOpenSink(INDEX_NAME, INDEX_TYPE, "");
    }

    private ElasticSearchSink createAndOpenSink(String indexName, String indexType, String indexPattern) throws IOException,
            InterruptedException {
        ElasticSearchSink sink = new ElasticSearchSink();
        sink.setLocalOnly(true);
        if (StringUtils.isNotBlank(indexName)) {
            sink.setIndexName(indexName);
        }
        if (StringUtils.isNotBlank(indexPattern)) {
            sink.setIndexPattern(indexPattern);
        }
        if (StringUtils.isNotBlank(indexType)) {
            sink.setIndexType(indexType);
        }
        sink.open();
        return sink;
    }

    private void assertBasicSearch(Event event) {
        assertCorrectResponse(4, event, executeSearch(matchAllQuery()));
    }

    private void assertPrioritySearch(Event event) {
        assertCorrectResponse(1, event, executeSearch(queryString("priority:INFO")));
    }

    private void assertHostSearch(Event event) {
        assertCorrectResponse(1, event, executeSearch(queryString("host:localhost")));
    }

    private void assertBodySearch(Event event) {
        assertCorrectResponse(1, event, executeSearch(fieldQuery("message.text", "goes")));
    }

    private void assertFieldsSearch(Event event) {
        assertCorrectResponse(1, event, executeSearch(fieldQuery("fields.attr1", "quux")));
    }

    private void assertJsonBody(Event event) {
        SearchResponse response = executeSearch(queryString("host:jsonbody"));
        @SuppressWarnings("unchecked")
        Map<String, Object> json = (Map<String, Object>) response.getHits().getAt(0).getSource().get("message");
        assertEquals("value", json.get("key"));
    }

    @SuppressWarnings("unchecked")
    private void assertComplexJsonBody(Event event) {
        SearchResponse response = executeSearch(queryString("host:complexjsonbody"));

        Map<String, Object> json = (Map<String, Object>) response.getHits().getAt(0).getSource().get("message");
        assertEquals("value", json.get("key"));

        json = (Map<String, Object>) json.get("complex");
        assertEquals("subvalue", json.get("subkey"));
    }

    private SearchResponse executeSearch(QueryBuilder query) {
        return executeSearch(query, INDEX_NAME, INDEX_TYPE);
    }

    private SearchResponse executeSearch(QueryBuilder query, String indexName, String indexType) {
        return searchClient.prepareSearch(indexName).setTypes(indexType)
                .setQuery(query)
                .execute()
                .actionGet();
    }

    private void assertCorrectResponse(int count, Event event, SearchResponse response) {
        SearchHits hits = response.getHits();

        assertEquals(count, hits.getTotalHits());

        SearchHit hit = hits.getAt(0);

        Map<String, Object> source = hit.getSource();

        assertEquals(event.getHost(), source.get("host"));
        assertEquals("1970-01-01T00:00:00.000Z", source.get("timestamp"));
        assertEquals(event.getPriority().name(), source.get("priority"));

        @SuppressWarnings("unchecked")
        Map<String, Object> message = (Map<String, Object>) source.get("message");
        assertEquals(new String(event.getBody()), message.get("text"));

        @SuppressWarnings("unchecked")
        Map<String, Object> fields = (Map<String, Object>) source.get("fields");

        assertEquals(new String(event.getAttrs().get("attr1")), fields.get("attr1"));
        assertEquals(new String(event.getAttrs().get("attr2")), fields.get("attr2"));
        @SuppressWarnings("unchecked")
        Map<String, Object> attr3 = (Map<String, Object>) fields.get("attr3");
        assertEquals("value", attr3.get("key"));
    }

}
TOP

Related Classes of org.elasticsearch.flume.ElasticSearchSinkTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.