Java tutorial
/** * * Copyright (c) 2015 NG Modular Oy. * * 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 io.spikex.core.helper; import static io.spikex.core.AbstractFilter.CONF_KEY_CHAIN_NAME; import static io.spikex.core.AbstractVerticle.CONF_KEY_CLUSTER_NAME; import static io.spikex.core.AbstractVerticle.CONF_KEY_CONF_PATH; import static io.spikex.core.AbstractVerticle.CONF_KEY_DATA_PATH; import static io.spikex.core.AbstractVerticle.CONF_KEY_HOME_PATH; import static io.spikex.core.AbstractVerticle.CONF_KEY_NODE_NAME; import static io.spikex.core.AbstractVerticle.CONF_KEY_TMP_PATH; import static io.spikex.core.AbstractVerticle.SHARED_METRICS_KEY; import static io.spikex.core.AbstractVerticle.SHARED_SENSORS_KEY; import io.spikex.core.util.HostOs; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.ISODateTimeFormat; import org.vertx.java.core.Vertx; import org.vertx.java.core.json.JsonObject; /** * Variable resolving utility class. * <p> * This class is not thread-safe. * * @author cli */ public final class Variables { private final Map<String, String> m_systemEnv; // System env variables private final Map<Object, Object> m_systemProps; // System properties private final Vertx m_vertx; // Used to get shared metric and sensor data private final String m_nodeName; private final String m_clusterName; private final String m_hostName; private final String m_spikexHome; private final String m_spikexConf; private final String m_spikexData; private final String m_spikexTmp; private final String m_chainName; // Built-ins private static final String BUILTIN_PREFIX = "#"; private static final String BUILTIN_NODE = "#node"; private static final String BUILTIN_CLUSTER = "#cluster"; private static final String BUILTIN_CHAIN = "#chain"; private static final String BUILTIN_HOST = "#host"; private static final String BUILTIN_DATE = "#date"; private static final String BUILTIN_TIMESTAMP = "#timestamp"; private static final String BUILTIN_NOW = "#now"; private static final String BUILTIN_NOW_EXTENDED = "#now("; private static final String BUILTIN_ENV = "#env."; private static final String BUILTIN_PROP = "#prop."; private static final String BUILTIN_METRIC = "#metric."; private static final String BUILTIN_SENSOR = "#sensor."; private static final String BUILTIN_SDF = "#+"; private static final String BUILTIN_SPIKEX_HOME = "#spikex.home"; private static final String BUILTIN_SPIKEX_CONF = "#spikex.conf"; private static final String BUILTIN_SPIKEX_DATA = "#spikex.data"; private static final String BUILTIN_SPIKEX_TMP = "#spikex.tmp"; private static final Pattern REGEXP_NOW = Pattern.compile("#now\\(" + "([A-Z][0-9\\w\\-\\+_/]+)?,?" // Timezone + "([\\+\\-]?[0-9]+h)?,?" // Hours + "([\\+\\-]?[0-9]+m)?,?" // Minutes + "([\\+\\-]?[0-9]+s)?" // Seconds + "\\)"); private static final String VAR_PREFIX = "%{"; private static final String VAR_SUFFIX = "}"; // Must be only one character long public static final String VAR_SPIKEX_HOME = VAR_PREFIX + BUILTIN_SPIKEX_HOME + VAR_SUFFIX; public static final String VAR_SPIKEX_CONF = VAR_PREFIX + BUILTIN_SPIKEX_CONF + VAR_SUFFIX; public static final String VAR_SPIKEX_DATA = VAR_PREFIX + BUILTIN_SPIKEX_DATA + VAR_SUFFIX; public static final String VAR_SPIKEX_TMP = VAR_PREFIX + BUILTIN_SPIKEX_TMP + VAR_SUFFIX; public Variables(final JsonObject nodeConfig) { this(nodeConfig, null); } public Variables(final JsonObject nodeConfig, final Vertx vertx) { // m_systemEnv = new ConcurrentHashMap(); m_systemEnv.putAll(System.getenv()); // m_systemProps = new ConcurrentHashMap(); Properties props = System.getProperties(); for (Entry<Object, Object> entry : props.entrySet()) { m_systemProps.put(entry.getKey(), entry.getValue()); } // m_vertx = vertx; // m_nodeName = nodeConfig.getString(CONF_KEY_NODE_NAME, ""); m_clusterName = nodeConfig.getString(CONF_KEY_CLUSTER_NAME, ""); m_spikexHome = nodeConfig.getString(CONF_KEY_HOME_PATH, ""); m_spikexConf = nodeConfig.getString(CONF_KEY_CONF_PATH, ""); m_spikexData = nodeConfig.getString(CONF_KEY_DATA_PATH, ""); m_spikexTmp = nodeConfig.getString(CONF_KEY_TMP_PATH, ""); m_chainName = nodeConfig.getString(CONF_KEY_CHAIN_NAME, ""); m_hostName = HostOs.hostName(); } public <T extends Object, V extends Object> T translate(final V value) { return translate(null, value); } public <T extends Object, V extends Object> T translate(final JsonObject event, final V value) { Object result = value; if (value != null && value instanceof String) { String strValue = (String) value; StringBuilder sb = new StringBuilder(); int strLen = strValue.length(); int pfxLen = VAR_PREFIX.length(); int pfxPos = strValue.indexOf(VAR_PREFIX); int sfxPos = strValue.indexOf(VAR_SUFFIX); int pos = 0; while (pfxPos >= 0 && sfxPos > pfxPos) { String var = strValue.substring(pfxPos + pfxLen, sfxPos); result = resolveValue(event, var); if (result != null) { if (pfxPos > 0 || sfxPos < (strLen - 1)) { sb.append(strValue.substring(pos, pfxPos)); sb.append(String.valueOf(result)); } } else { sb.append(strValue.substring(pos, sfxPos + 1)); } if (sfxPos < (strLen - 1)) { pos = sfxPos + 1; pfxPos = strValue.indexOf(VAR_PREFIX, pos); sfxPos = strValue.indexOf(VAR_SUFFIX, pos); } else { pos = strLen; pfxPos = -1; // break } } if (sb.length() > 0) { if (pos < strLen) { sb.append(strValue.substring(pos, strLen)); } result = sb.toString(); } } return (T) (result == null ? "" : result); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("node.name: "); sb.append(m_nodeName); sb.append(",cluster.name: "); sb.append(m_clusterName); sb.append(",host.name: "); sb.append(m_hostName); sb.append(",spikex.home: "); sb.append(m_spikexHome); sb.append(",spikex.conf: "); sb.append(m_spikexConf); sb.append(",spikex.data: "); sb.append(m_spikexData); sb.append(",spikex.tmp: "); sb.append(m_spikexTmp); sb.append(",chain.name: "); sb.append(m_chainName); sb.append(",env-vars: "); sb.append(m_systemEnv); sb.append(",sys-props: "); sb.append(m_systemProps); sb.append(",metrics: {"); { Set<Entry<Object, Object>> entries = m_vertx.sharedData().getMap(SHARED_METRICS_KEY).entrySet(); for (Entry entry : entries) { sb.append(String.valueOf(entry.getKey())); sb.append("="); sb.append(String.valueOf(entry.getValue())); sb.append(", "); } } sb.append(",sensors: {"); { Set<Entry<Object, Object>> entries = m_vertx.sharedData().getMap(SHARED_SENSORS_KEY).entrySet(); for (Entry entry : entries) { sb.append(String.valueOf(entry.getKey())); sb.append("="); sb.append(String.valueOf(entry.getValue())); sb.append(", "); } } sb.append("}"); return sb.toString(); } private Object resolveValue(final JsonObject event, final String var) { Object value = null; if (var.length() > 0) { if (var.startsWith(BUILTIN_PREFIX)) { DateTime dtNow; DateTimeFormatter fmt; if (var.startsWith(BUILTIN_SDF)) { // Simple date format String pattern = var.substring(BUILTIN_SDF.length()); dtNow = new DateTime(DateTimeZone.UTC); fmt = DateTimeFormat.forPattern(pattern); value = fmt.print(dtNow); } else if (var.startsWith(BUILTIN_ENV)) { // env Object val = m_systemEnv.get(var.substring(BUILTIN_ENV.length())); value = (val != null ? String.valueOf(val) : ""); } else if (var.startsWith(BUILTIN_PROP)) { // prop Object val = m_systemProps.get(var.substring(BUILTIN_PROP.length())); value = (val != null ? String.valueOf(val) : ""); } else if (var.startsWith(BUILTIN_METRIC)) { // metrics if (m_vertx != null) { Map<String, Object> values = m_vertx.sharedData().getMap(SHARED_METRICS_KEY); value = values.get(var.substring(BUILTIN_METRIC.length())); } } else if (var.startsWith(BUILTIN_SENSOR)) { // sensor if (m_vertx != null) { Map<String, Object> values = m_vertx.sharedData().getMap(SHARED_SENSORS_KEY); value = values.get(var.substring(BUILTIN_SENSOR.length())); } } else if (var.startsWith(BUILTIN_NOW_EXTENDED)) { // now extended with timezone and time offset DateTime dt = Variables.createDateTimeNow(var); value = dt.getMillis(); } else { switch (var) { case BUILTIN_NODE: value = m_nodeName; break; case BUILTIN_CLUSTER: value = m_clusterName; break; case BUILTIN_SPIKEX_HOME: value = m_spikexHome; break; case BUILTIN_SPIKEX_CONF: value = m_spikexConf; break; case BUILTIN_SPIKEX_DATA: value = m_spikexData; break; case BUILTIN_SPIKEX_TMP: value = m_spikexTmp; break; case BUILTIN_CHAIN: value = m_chainName; break; case BUILTIN_HOST: value = m_hostName; break; case BUILTIN_DATE: dtNow = new DateTime(DateTimeZone.UTC); fmt = ISODateTimeFormat.basicDate(); value = fmt.print(dtNow); break; case BUILTIN_TIMESTAMP: dtNow = new DateTime(DateTimeZone.UTC); fmt = ISODateTimeFormat.basicDateTime(); value = fmt.print(dtNow); break; case BUILTIN_NOW: value = System.currentTimeMillis(); break; default: value = var; // Just return the variable def break; } } } else { // // Retrieve value from existing field in the event // if (event != null) { value = event.getValue(var); } } } return value; } public static DateTime createDateTimeNow(final String var) { DateTime dt; // #now // #now(UTC) // #now(UTC,0h,-10m,0s) // #now(0h,-10m,0s) // #now(30m) Matcher m = REGEXP_NOW.matcher(var); // // Timezone // String tz = null; boolean found = m.find(); if (found) { tz = m.group(1); } // // Hours // int hours = 0; if (found) { String val = m.group(2); if (val != null) { hours = Integer.parseInt(val.substring(0, val.length() - 1)); } } // // Minutes // int mins = 0; if (found) { String val = m.group(3); if (val != null) { mins = Integer.parseInt(val.substring(0, val.length() - 1)); } } // // Seconds // int secs = 0; if (found) { String val = m.group(4); if (val != null) { secs = Integer.parseInt(val.substring(0, val.length() - 1)); } } System.out.println("var: " + var + " tz: " + tz + " hours: " + hours + " mins: " + mins + " secs: " + secs); if (tz != null) { dt = new DateTime(DateTimeZone.forID(tz)); } else { dt = new DateTime(); } dt = dt.plusHours(hours); dt = dt.plusMinutes(mins); dt = dt.plusSeconds(secs); return dt; } }