org.groggy.elasticsearch.river.injector.InjectorRiverConfig.java Source code

Java tutorial

Introduction

Here is the source code for org.groggy.elasticsearch.river.injector.InjectorRiverConfig.java

Source

/* Copyright 2013 Endgame, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.groggy.elasticsearch.river.injector;

import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.river.RiverSettings;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class InjectorRiverConfig {

    final long statsOutputInterval;
    final long tickInterval;
    final long interMessageDelay;
    final long interBulkDelay;
    long uuid = 0;

    final DateTimeFormatter indexTimeFormatter;
    final String esIndex;
    final String esDocumentType;
    final String esDocumentIdPrefix;
    final String[] itemKey;
    final Value[] itemValue;
    final Object[] completeSources;
    final Object[] publishedSources;

    final boolean isRiver;
    final Clock clock;
    int esRiverBulkSize;
    int totalMessageNumber;

    public String toString() {
        return "tick=" + tickInterval + ";bulkSize=" + esRiverBulkSize + ";sleep=" + interMessageDelay + ";index="
                + esIndex + ";type=" + esDocumentType;
    }

    /**
     * Setup a configuration. 
     * @param settings the settings
     */
    public InjectorRiverConfig(Map<String, Object> settings) {
        isRiver = XContentMapValues.nodeBooleanValue(settings.get("is-river"), true);
        totalMessageNumber = XContentMapValues.nodeIntegerValue(settings.get("load_total_messages"), 0);
        esRiverBulkSize = XContentMapValues.nodeIntegerValue(settings.get("es_river_bulk_size"), 5000);
        esDocumentIdPrefix = XContentMapValues.nodeStringValue(settings.get("es_document_id_prefix"), "");
        esDocumentType = XContentMapValues.nodeStringValue(settings.get("es_type"), "groggy");
        tickInterval = getTimeValue("load_tick_interval", 1, settings);
        interMessageDelay = getTimeValue("load_inter_message_delay", 0, settings);
        interBulkDelay = getTimeValue("load_inter_bulk_delay", 0, settings);
        statsOutputInterval = getTimeValue("load_stats_publish_interval", 10000, settings);
        String startTime = XContentMapValues.nodeStringValue(settings.get("load_start_time"), null);
        if (startTime != null) {
            String timeFormat = XContentMapValues.nodeStringValue(settings.get("load_start_time_format"),
                    "yyyy.MM.dd");
            DateTimeFormatter fmt = DateTimeFormat.forPattern(timeFormat);
            DateTime start = fmt.parseDateTime(startTime);
            this.clock = new Clock(start, (int) tickInterval);
        } else {
            this.clock = new Clock(new DateTime(), (int) tickInterval);
        }

        /**
         * take the required elasticsearch index. The input string is somthing like
         * "logstash-%{yyy.MM.dd}", or "logstash-%{yyyy.MM.dd.hh}".
         * Form that we compute this.index as "logstash-" and a DateTimeFormat corresponding
         * to the "yyy.MM.dd" part.
         */
        String _index = XContentMapValues.nodeStringValue(settings.get("es_index"), null);
        if (_index != null) {
            String regex = "%\\{(.*?)\\}";
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(_index);
            if (matcher.find()) {
                String dateFormat = matcher.group(1);
                this.esIndex = _index.replaceAll(regex, "");
                this.indexTimeFormatter = DateTimeFormat.forPattern(dateFormat);
            } else {
                this.esIndex = _index;
                this.indexTimeFormatter = null;
            }
        } else {
            this.esIndex = null;
            this.indexTimeFormatter = null;
        }

        @SuppressWarnings("unchecked")
        List<Map<String, Object>> template = (List<Map<String, Object>>) settings.get("es_fields");
        itemKey = new String[template.size()];
        itemValue = new Value[template.size()];
        int itemsIndex = 0;
        int outsideRiverCount = 0;
        for (int i = 0; i < template.size(); i++) {
            Map<String, Object> item = template.get(i);
            itemKey[itemsIndex] = (String) item.get("key");
            boolean includeOutsideRiver = XContentMapValues.nodeBooleanValue(item.get("include-outside-river"),
                    false);
            switch ((String) item.get("type")) {
            case "data":
                itemValue[itemsIndex] = new Data((String) item.get("value"));
                break;
            case "ipv4":
                itemValue[itemsIndex] = new Ipv4((String) item.get("format"));
                break;
            case "counter": {
                int min = XContentMapValues.nodeIntegerValue(item.get("min"), 0);
                int max = XContentMapValues.nodeIntegerValue(item.get("max"), 0);
                itemValue[itemsIndex] = new Count(min, max);
            }
                break;
            case "random": {
                int min = XContentMapValues.nodeIntegerValue(item.get("min"), 0);
                int max = XContentMapValues.nodeIntegerValue(item.get("max"), 0);
                itemValue[itemsIndex] = new RandomInt(min, max);
            }
                break;
            case "timestamp":
                String format = XContentMapValues.nodeStringValue(item.get("format"), null);
                itemValue[itemsIndex] = new Timestamper(clock, format);
                break;
            default:
                throw new IllegalArgumentException("unknown template item type " + (String) item.get("type"));
            }
            if (includeOutsideRiver) {
                itemValue[itemsIndex].includeOutsideRiver();
                outsideRiverCount++;
            }
            itemsIndex++;
        }
        completeSources = new Object[itemsIndex * 2];
        publishedSources = new Object[outsideRiverCount * 2];
    }

    /**
     * Return a configuration time value in millisecond
     * @param key the property key name
     * @param def the default value (in millisecond)
     * @param settings the input configuration map
     * @return
     */
    static long getTimeValue(String key, long def, Map<String, Object> settings) {
        String tv = XContentMapValues.nodeStringValue(settings.get(key), null);
        if (tv == null) {
            return def;
        }
        return TimeValue.parseTimeValue(tv, TimeValue.timeValueMillis(def)).getMillis();
    }

    public InjectorRiverConfig(RiverSettings settings) {
        this(settings.settings());
    }

    public Object[] getSource() {
        for (int i = 0; i < itemValue.length; i++) {
            completeSources[2 * i] = itemKey[i];
            completeSources[2 * i + 1] = itemValue[i].getNext(completeSources, 2 * i - 1);
        }
        if (!isRiver) {
            int publishedItemIndex = 0;
            for (int i = 0; i < completeSources.length; i += 2) {
                int itemIndex = i / 2;
                if (itemValue[itemIndex].mustBeIncludedOutsideRiver()) {
                    publishedSources[publishedItemIndex++] = itemKey[itemIndex];
                    publishedSources[publishedItemIndex++] = completeSources[i + 1];
                }
            }
            return publishedSources;
        } else {
            return completeSources;
        }
    }

    public Clock getClock() {
        return clock;
    }

    public String getIndex() {
        String indexNow = esIndex + clock.now().toString(indexTimeFormatter);
        return indexNow;
    }

    public String getType() {
        return esDocumentType;
    }

    public String getEsDocumentId() {
        return esDocumentIdPrefix + uuid++;
    }

    public int getEsRiverBulkSize() {
        return esRiverBulkSize;
    }

    public int getTotalMessageNumber() {
        return totalMessageNumber;
    }
}