package com.rubiconproject.oss.kv.distributed.impl;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import com.rubiconproject.oss.kv.backends.ConnectionFactory;
import com.rubiconproject.oss.kv.backends.UriConnectionFactory;
import com.rubiconproject.oss.kv.distributed.Configuration;
import com.rubiconproject.oss.kv.distributed.Configurator;
import com.rubiconproject.oss.kv.distributed.NodeStore;
public class PropertiesConfigurator implements Configurator {
public static final String SYNC_OP_THREAD_POOL = "syncpool.threads";
public static final String SYNC_OP_MAX_QUEUE_SIZE = "syncpool.maxQueueSize";
public static final String ASYNC_OP_THREAD_POOL = "asyncpool.threads";
public static final String ASYNC_OP_MAX_QUEUE_SIZE = "asyncpool.maxQueueSize";
public static final String MAX_NODE_ERROR_COUNT = "node.maxErrorCount";
public static final String NODE_STORE = "nodestore.implementation";
public static final String NODE_STORE_URL = "nodestore.url";
public static final String READ_OPERATION_TIMEOUT = "read.timeout";
public static final String READ_REPLICAS = "read.replicas";
public static final String REQUIRED_READS = "read.required";
public static final String REQUIRED_WRITES = "write.required";
public static final String WRITE_OPERATION_TIMEOUT = "write.timeout";
public static final String WRITE_REPLICAS = "write.replicas";
public static final String BACKFILL_NULL_GET_REQUESTS = "backfill.nullGets";
public static final String BACKFILL_FAILED_GET_REQUESTS = "backfill.failedGets";
private volatile Configuration config;
public PropertiesConfigurator() {
}
public PropertiesConfigurator(File file) throws IOException {
load(file);
}
public PropertiesConfigurator(InputStream is) throws IOException {
load(is);
}
public PropertiesConfigurator(Properties p) throws IOException {
load(p);
}
public PropertiesConfigurator(String path) throws IOException {
InputStream is = getClass().getResourceAsStream(path);
try {
load(is);
} finally {
is.close();
}
}
public void load(File file) throws IOException {
FileInputStream fis = new FileInputStream(file);
try {
load(fis);
} finally {
fis.close();
}
}
public void load(InputStream in) throws IOException {
Properties p = new Properties();
p.load(in);
load(p);
}
public void load(Properties props) throws IOException {
this.config = getConfig(props);
}
public Configuration getConfiguration() throws IOException {
return config;
}
private Configuration getConfig(Properties p)
throws IllegalArgumentException {
ConnectionFactory cf = new UriConnectionFactory();
int syncOperationThreadPoolCount = getIntProperty(p,
SYNC_OP_THREAD_POOL, 100);
int syncOperationMaxQueueSize = getIntProperty(p,
SYNC_OP_MAX_QUEUE_SIZE, 100);
int asyncOperationThreadPoolCount = getIntProperty(p,
ASYNC_OP_THREAD_POOL, 10);
int asyncOperationMaxQueueSize = getIntProperty(p,
ASYNC_OP_MAX_QUEUE_SIZE, 100);
Configuration config = new Configuration();
config
.setAsyncOperationQueue(new NonPersistentThreadPoolOperationQueue(
p, cf, asyncOperationThreadPoolCount,
asyncOperationMaxQueueSize));
config.setConnectionFactory(cf);
config
.setMaxNodeErrorCount(getIntProperty(p, MAX_NODE_ERROR_COUNT,
100));
config.setNodeErrorCountPeriod(TimeUnit.MINUTES);
config.setNodeStore(getNodeStore(NODE_STORE, p));
config.setReadOperationTimeout(getIntProperty(p,
READ_OPERATION_TIMEOUT, 500));
config.setReadReplicas(getIntProperty(p, READ_REPLICAS, 3));
config.setRequiredReads(getIntProperty(p, REQUIRED_READS, 2));
config.setRequiredWrites(getIntProperty(p, REQUIRED_WRITES, 2));
config
.setSyncOperationQueue(new NonPersistentThreadPoolOperationQueue(
p, cf, syncOperationThreadPoolCount,
syncOperationMaxQueueSize));
config.setWriteOperationTimeout(getIntProperty(p,
WRITE_OPERATION_TIMEOUT, 500));
config.setWriteReplicas(getIntProperty(p, WRITE_REPLICAS, 3));
config.setFillNullGetResults(getBooleanProperty(p,
BACKFILL_NULL_GET_REQUESTS, true));
config.setFillErrorGetResults(getBooleanProperty(p,
BACKFILL_FAILED_GET_REQUESTS, false));
return config;
}
private NodeStore getNodeStore(String name, Properties props)
throws IllegalArgumentException {
try {
Class<NodeStore> cls = (Class<NodeStore>) Class.forName(props
.getProperty(NODE_STORE));
Object obj = cls.newInstance();
NodeStore ns = (NodeStore) obj;
ns.setProperties(props);
return ns;
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
private int getIntProperty(Properties p, String name, int defaultValue) {
String value = p.getProperty(name);
if (value == null) {
value = Integer.toString(defaultValue);
}
return Integer.parseInt(value);
}
public boolean getBooleanProperty(Properties p, String name,
boolean defaultValue) {
String value = p.getProperty(name);
if (value == null) {
value = Boolean.toString(defaultValue);
}
return Boolean.parseBoolean(value);
}
}