Java tutorial
/* 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; } }