package com.tinkerpop.rexster.server;
import com.tinkerpop.rexster.Tokens;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.log4j.Logger;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* RexsterProperties are settings that come from the rexster.xml configuration file appended with other in server
* settings that come from the command line.
*
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
public class RexsterProperties extends FileAlterationListenerAdaptor {
private static final Logger logger = Logger.getLogger(RexsterProperties.class);
private XMLConfiguration configuration;
private final List<RexsterPropertiesListener> listeners = new ArrayList<RexsterPropertiesListener>();
private final Map<String, RexsterPropertyOverride> overrides = new HashMap<String,RexsterPropertyOverride>();
public RexsterProperties(final XMLConfiguration configuration) {
this.configuration = configuration;
}
public RexsterProperties(final String rexsterXmlFileLocation) {
readConfigurationFromFile(rexsterXmlFileLocation);
}
private void readConfigurationFromFile(final String rexsterXmlFileLocation) {
this.configuration = new XMLConfiguration();
final String rexsterHome = System.getenv("REXSTER_HOME");
final String rexsterXmlWithHome = rexsterHome == null ? rexsterXmlFileLocation : rexsterHome + File.separator + rexsterXmlFileLocation;
if (rexsterHome != null)
logger.info(String.format("REXSTER_HOME is set, trying config at [%s]", rexsterXmlWithHome));
File rexsterXmlFile = new File(rexsterXmlWithHome);
try {
// load either the rexster.xml from the command line or the default rexster.xml in the root of the
// working directory
configuration.load(new FileReader(rexsterXmlWithHome));
logger.info(String.format("Using [%s] as configuration source.", rexsterXmlFile.getAbsolutePath()));
} catch (Exception e) {
final String msg = String.format("Could not load configuration from [%s]", rexsterXmlFile.getAbsolutePath());
logger.warn(msg);
throw new RuntimeException(msg);
}
}
public XMLConfiguration getConfiguration() {
return this.configuration;
}
public List<HierarchicalConfiguration> getGraphConfigurations() {
return configuration.configurationsAt(Tokens.REXSTER_GRAPH_PATH);
}
public List<HierarchicalConfiguration> getReporterConfigurations() {
return configuration.configurationsAt(Tokens.REXSTER_REPORTER_PATH);
}
public Long getConfigCheckInterval() {
return configuration.getLong("config-check-interval",
new Long(RexsterSettings.DEFAULT_CONFIG_CHECK_INTERVAL));
}
public Long getRexProSessionMaxIdle() {
return configuration.getLong("rexpro.session-max-idle",
new Long(RexsterSettings.DEFAULT_REXPRO_SESSION_MAX_IDLE));
}
public Long getRexProSessionCheckInterval() {
return configuration.getLong("rexpro.session-check-interval",
new Long(RexsterSettings.DEFAULT_REXPRO_SESSION_CHECK_INTERVAL));
}
public Integer getRexsterShutdownPort() {
return configuration.getInteger("shutdown-port", new Integer(RexsterSettings.DEFAULT_SHUTDOWN_PORT));
}
public String getRexsterShutdownHost() {
return configuration.getString("shutdown-host", RexsterSettings.DEFAULT_HOST);
}
public List<HierarchicalConfiguration> getScriptEngines() {
return this.configuration.configurationsAt(Tokens.REXSTER_SCRIPT_ENGINE_PATH);
}
public HierarchicalConfiguration getSecuritySettings() {
try {
return configuration.configurationAt(Tokens.REXSTER_SECURITY_AUTH);
} catch (IllegalArgumentException iae) {
return null;
}
}
public void addListener(final RexsterPropertiesListener listener) {
this.listeners.add(listener);
}
public void addOverride(final String overrideKey, final Object overrideValue) {
this.configuration.setProperty(overrideKey, overrideValue);
this.overrides.put(overrideKey, new RexsterPropertyOverride(overrideKey, overrideValue));
}
public void removeOverride(final String overrideKey) {
this.overrides.remove(overrideKey);
}
@Override
public void onFileChange(final File file) {
logger.info(String.format("File settings have changed. Rexster is reloading [%s]", file.getAbsolutePath()));
readConfigurationFromFile(file.getAbsolutePath());
for (RexsterPropertyOverride override : overrides.values()) {
configuration.setProperty(override.getKeyToOverride(), override.getOverrideValue());
}
for (RexsterPropertiesListener listener : listeners) {
listener.propertiesChanged(configuration);
}
}
public interface RexsterPropertiesListener {
void propertiesChanged(final XMLConfiguration configuration);
}
class RexsterPropertyOverride {
private final String keyToOverride;
private final Object overrideValue;
public RexsterPropertyOverride(final String keyToOverride, final Object overrideValue) {
this.keyToOverride = keyToOverride;
this.overrideValue = overrideValue;
}
public String getKeyToOverride() {
return keyToOverride;
}
public Object getOverrideValue() {
return overrideValue;
}
}
}