/**
* Copyright 2013-2014 Recruit Technologies Co., Ltd. and contributors
* (see CONTRIBUTORS.md)
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. A copy of the
* License is distributed with this work in the LICENSE.md file. You may
* also obtain a copy of the License from
*
* 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.gennai.gungnir;
import static org.gennai.gungnir.GungnirConst.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.gennai.gungnir.utils.GungnirUtils;
import org.gennai.gungnir.utils.TypeCastException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import backtype.storm.utils.Utils;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
public final class GungnirConfig extends LinkedHashMap<String, Object> {
private static final long serialVersionUID = SERIAL_VERSION_UID;
private static final Logger LOG = LoggerFactory.getLogger(GungnirConfig.class);
public static final String GUNGNIR_SERVER_PORT = "gungnir.server.port";
public static final String SESSION_TIMEOUT_SECS = "session.timeout.secs";
public static final String COMMAND_PROCESSOR_CACHE_SIZE = "command.processor.cache.size";
public static final String GUNGNIR_NODE_PATH = "gungnir.node.path";
public static final String TUPLE_STORE_SERVER_PORT = "tuple.store.server.port";
public static final String TRACKING_COOKIE_MAXAGE = "tracking.cookie.maxage";
public static final String PERSISTENT_DESER_QUEUE_SIZE = "persistent.deser.queue.size";
public static final String PERSISTENT_DESER_PARALLELISM = "persistent.deser.parallelism";
public static final String PERSISTENT_DESERIALIZER = "persistent.deserializer";
public static final String PERSISTENT_EMITTER_QUEUE_SIZE = "persistent.emitter.queue.size";
public static final String PERSISTENT_EMITTER_PARALLELISM = "persistent.emitter.parallelism";
public static final String PERSISTENT_EMIT_TUPLES_MAX = "persistent.emit.tuples.max";
public static final String PERSISTENT_EMIT_TUPLES_MAX_SIZE = "persistent.emit.tuples.max.size";
public static final String PERSISTENT_EMITTER = "persistent.emitter";
public static final String REWRITE_RULES = "rewrite.rules";
public static final String REWRITE_PATTERN = "pattern";
public static final String REWRITE_TARGET = "target";
public static final String CLUSTER_MODE = "cluster.mode";
public static final String LOCAL_CLUSTER = "local";
public static final String DISTRIBUTED_CLUSTER = "distributed";
public static final String CLUSTER_ZOOKEEPER_SERVERS = "cluster.zookeeper.servers";
public static final String CLUSTER_ZOOKEEPER_SESSION_TIMEOUT =
"cluster.zookeeper.session.timeout";
public static final String CLUSTER_ZOOKEEPER_CONNECTION_TIMEOUT =
"cluster.zookeeper.connection.timeout";
public static final String CLUSTER_ZOOKEEPER_RETRY_TIMES = "cluster.zookeeper.retry.times";
public static final String CLUSTER_ZOOKEEPER_RETRY_INTERVAL = "cluster.zookeeper.retry.interval";
public static final String GUNGNIR_ADMIN_SERVER_PORT = "gungnir.admin.server.port";
public static final String GUNGNIR_ADMIN_SERVER_BACKLOG = "gungnir.admin.server.backlog";
public static final String STORM_CLUSTER_MODE = "storm.cluster.mode";
public static final String STORM_NIMBUS_HOST = "storm.nimbus.host";
public static final String TOPOLOGY_WORKERS = "topology.workers";
public static final String TOPOLOGY_STATUS_CHECK_TIMES = "topology.status.check.times";
public static final String TOPOLOGY_STATUS_CHECK_INTERVAL = "topology.status.check.interval";
public static final String DEFAULT_PARALLELISM = "default.parallelism";
public static final String LOCAL_DIR = "gungnir.local.dir";
public static final String METASTORE = "metastore";
public static final String METASTORE_MONGODB_SERVERS = "metastore.mongodb.servers";
public static final String METASTORE_NAME = "metastore.name";
public static final String KAFKA_BROKERS = "kafka.brokers";
public static final String KAFKA_REQUIRED_ACKS = "kafka.required.acks";
public static final String KAFKA_PRODUCER_TYPE = "kafka.producer.type";
public static final String KAFKA_AUTO_COMMIT_INTERVAL = "kafka.auto.commit.interval";
public static final String KAFKA_ZOOKEEPER_SERVERS = "kafka.zookeeper.servers";
public static final String KAFKA_ZOOKEEPER_SESSION_TIMEOUT = "kafka.zookeeper.session.timeout";
public static final String KAFKA_ZOOKEEPER_CONNECTION_TIMEOUT =
"kafka.zookeeper.connection.timeout";
public static final String KAFKA_ZOOKEEPER_SYNC_TIMEOUT = "kafka.zookeeper.sync.timeout";
public static final String KAFKA_ZOOKEEPER_RETRY_TIMES = "kafka.zookeeper.retry.times";
public static final String KAFKA_ZOOKEEPER_RETRY_INTERVAL = "kafka.zookeeper.retry.interval";
public static final String EXPORT_RETRY_TIMES = "export.retry.times";
public static final String EXPORT_RETRY_INTERVAL = "export.retry.interval";
public static final String COMPONENT_SNAPSHOT_QUEUE_SIZE = "component.snapshot.queue.size";
public static final String COMPONENT_SNAPSHOT_PARALLELISM = "component.snapshot.parallelism";
public static final String SPOUT_OPERATOR_QUEUE_SIZE = "spout.operator.queue.size";
public static final String EMIT_OPERATOR_QUEUE_SIZE = "emit.operator.queue.size";
public static final String EMIT_OPERATOR_EMIT_TUPLES_MAX = "emit.operator.emit.tuples.max";
public static final String TUPLEJOIN_SEEK_SIZE = "tuplejoin.seek.size";
public static final String LOG_APPEND_QUEUE_SIZE = "log.append.queue.size";
public static final String LOG_APPEND_RECONNECT_DELAY = "log.append.reconnect.delay";
public static final String DEBUG_ENABLED = "debug";
public static final String LOG_RECEIVER_HOST = "log.receiver.host";
public static final String LOG_RECEIVER_PORT = "log.receiver.port";
public static final String DEBUG_LOG_APPEND_QUEUE_SIZE = "debug.log.append.queue.size";
public static final String DEBUG_LOG_APPEND_RECONNECT_DELAY = "debug.log.append.reconnect.delay";
public static final String METRICS_REPORTERS = "metrics.reporters";
public static final String METRICS_REPORTER = "reporter";
public static final String METRICS_INTERVAL_SECS = "interval.secs";
public static final String METRICS_REPORTER_STATSD_HOST = "statsd.host";
public static final String METRICS_REPORTER_STATSD_PORT = "statsd.port";
public static final String METRICS_REPORTER_STATSD_PREFIX = "statsd.prefix";
public static final String TOPOLOGY_METRICS_ENABLED = "topology.metrics.enabled";
public static final String TOPOLOGY_METRICS_CONSUMER = "topology.metrics.consumer";
public static final String TOPOLOGY_METRICS_CONSUMER_PARALLELISM =
"topology.metrics.consumer.parallelism";
public static final String TOPOLOGY_METRICS_INTERVAL_SECS = "topology.metrics.interval.secs";
public static final String TOPOLOGY_STATS_SAMPLE_RATE = "topology.stats.sample.rate";
public static final String METRICS_STATSD_HOST = "metrics.statsd.host";
public static final String METRICS_STATSD_PORT = "metrics.statsd.port";
public static final String METRICS_CONSUMER_PREFIX = "metrics.consumer.prefix";
public static final String METRICS_REPORTER_PREFIX = "metrics.reporter.prefix";
public static final String GUNGNIR_SERVER_HOST = "gungnir.server.host";
public static final String TUPLE_STORE_SERVER_HOST = "tuple.store.server.host";
public static final String GUNGNIR_CLIENT_RESPONSE_TIMEOUT = "gungnir.client.response.timeout";
public static final String LOG_BUFFER_MAX = "log.buffer.max";
public static final String CLASS_PATH = "gungnir.class.path";
private static final String DEFAULTS_CONFIG_FILE = "gungnir-defaults.yaml";
private static final String CONFIG_FILE = "gungnir.yaml";
private static final String GUNGNIR_CONFIG_FILE = "gungnir.conf.file";
private GungnirConfig() {
}
private GungnirConfig(Map<String, Object> config) {
super(config);
}
@SuppressWarnings("unchecked")
private Object clone(Object value) {
if (value instanceof List) {
List<Object> copy = Lists.newArrayList();
for (Object v : (List<Object>) value) {
copy.add(clone(v));
}
return copy;
} else if (value instanceof Map) {
Map<String, Object> copy = Maps.newLinkedHashMap();
for (Map.Entry<String, Object> entry : ((Map<String, Object>) value).entrySet()) {
copy.put(entry.getKey(), clone(entry.getValue()));
}
return copy;
} else {
return value;
}
}
private GungnirConfig(GungnirConfig c) {
for (Map.Entry<String, Object> entry : c.entrySet()) {
put(entry.getKey(), clone(entry.getValue()));
}
}
@SuppressWarnings("unchecked")
public static GungnirConfig readGugnirConfig() {
GungnirConfig config = new GungnirConfig();
config.putAll(Utils.findAndReadConfigFile(DEFAULTS_CONFIG_FILE, true));
String confFile = System.getProperty(GUNGNIR_CONFIG_FILE);
if (confFile == null || confFile.isEmpty()) {
config.putAll(Utils.findAndReadConfigFile(CONFIG_FILE, false));
} else {
BufferedReader reader = null;
try {
reader = Files.newReader(new File(confFile), Charsets.UTF_8);
Yaml yaml = new Yaml(new SafeConstructor());
Map<String, Object> ret = (Map<String, Object>) yaml.load(reader);
if (ret != null) {
config.putAll(ret);
}
} catch (IOException e) {
LOG.warn("Failed to read " + confFile);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
LOG.warn("Failed to close " + confFile);
}
}
}
}
Map<String, Object> stormConf = Utils.readStormConfig();
for (Map.Entry<String, Object> entry : config.entrySet()) {
if (entry.getValue() instanceof String) {
String value = (String) entry.getValue();
if (value.startsWith("${") && value.endsWith("}")) {
String key = value.substring(2, value.length() - 1);
config.put(entry.getKey(), stormConf.get(key));
}
}
}
return config;
}
public static GungnirConfig wrap(Map<String, Object> config) {
return new GungnirConfig(config);
}
public String getString(String key) {
return (String) get(key);
}
public Byte getByte(String key) {
Object value = get(key);
if (value != null) {
try {
return GungnirUtils.toTinyint(value);
} catch (TypeCastException ignore) {
ignore = null;
}
}
return null;
}
public Short getShort(String key) {
Object value = get(key);
if (value != null) {
try {
return GungnirUtils.toSmallint(value);
} catch (TypeCastException ignore) {
ignore = null;
}
}
return null;
}
public Integer getInteger(String key) {
Object value = get(key);
if (value != null) {
try {
return GungnirUtils.toInt(value);
} catch (TypeCastException ignore) {
ignore = null;
}
}
return null;
}
public Long getLong(String key) {
Object value = get(key);
if (value != null) {
try {
return GungnirUtils.toBigint(value);
} catch (TypeCastException ignore) {
ignore = null;
}
}
return null;
}
public Float getFloat(String key) {
Object value = get(key);
if (value != null) {
try {
return GungnirUtils.toFloat(value);
} catch (TypeCastException ignore) {
ignore = null;
}
}
return null;
}
public Double getDouble(String key) {
Object value = get(key);
if (value != null) {
try {
return GungnirUtils.toDouble(value);
} catch (TypeCastException ignore) {
ignore = null;
}
}
return null;
}
public Boolean getBoolean(String key) {
Object value = get(key);
if (value != null) {
return GungnirUtils.toBoolean(value);
}
return false;
}
public byte[] getBinary(String key) {
return (byte[]) get(key);
}
@SuppressWarnings("unchecked")
public <T> List<T> getList(String key) {
return (List<T>) get(key);
}
public InetSocketAddress getAddress(String key) {
Object value = get(key);
if (value != null) {
if (value instanceof String) {
String address = (String) value;
if (!address.isEmpty()) {
int index = address.indexOf(':');
if (index > 0) {
String host = address.substring(0, index);
int port = Integer.valueOf(address.substring(index + 1));
return new InetSocketAddress(host, port);
}
}
} else if (value instanceof Integer) {
return new InetSocketAddress((Integer) value);
}
}
return null;
}
public Class<?> getClass(String key) throws ClassNotFoundException {
String className = getString(key);
return Class.forName(className);
}
@Override
public GungnirConfig clone() {
return new GungnirConfig(this);
}
}