package dk.kb.yggdrasil.config;
import java.io.File;
import java.util.LinkedHashMap;
import java.util.Map;
import dk.kb.yggdrasil.exceptions.ArgumentCheck;
import dk.kb.yggdrasil.exceptions.YggdrasilException;
import dk.kb.yggdrasil.utils.YamlTools;
/** The class reading the yggdrasil.yml file. */
public class YggdrasilConfig {
/** The configDir where the yggdrasilConfigFile was located. */
private File configdir;
/** The database directory property. */
private static final String DATABASE_DIR_PROPERTY = "database_dir";
/** The database directory. (created if it doesn't exist. ) */
private final File databaseDir;
/** The temporary directory property. */
private static final String TEMPORARY_DIR_PROPERTY = "temporary_dir";
/** The temporary directory. (created if it doesn't exist. )*/
private final File tmpDir;
/** The monitor endpoint port property. */
private static final String MONITOR_PORT_PROPERTY = "monitor_port";
/** The default value for the monitor port */
private static final Integer DEFAULT_MONITOR_PORT_PROPERTY = 1938;
/** The monitor port for the RunState service endpoint */
private final int monitorPort;
/** The property for the warc size limit. */
private static final String WARC_SIZE_LIMIT_PROPERTY = "warc_size_limit";
/** The default value for the warc size limit: 1 GB. */
private static final Long DEFAULT_WARC_SIZE_LIMIT = 1000000000L;
/** The warc size limit. */
private final long warcSizeLimit;
/** The property for the upload wait limit. */
private static final String UPLOAD_WAIT_LIMIT_PROPERTY = "upload_wait_limit";
/** The default value for the upload wait limit: 10 min.*/
private static final Long DEFAULT_UPLOAD_WAIT_LIMIT = 600000L;
/** The upload wait limit.*/
private final long uploadWaitLimit;
/** The property for the interval for checking the conditions for the WARC files. */
private static final String CHECK_WARC_CONDITION_INTERVAL_PROPERTY = "check_conditions";
/** The default value for the interval.*/
private static final Long DEFAULT_CHECK_WARC_CONDITION_INTERVAL = 60000L;
/** The interval for checking WARC conditions. */
private final Long checkWarcConditionInterval;
/**
* Constructor for class reading the general Yggdrasil config file.
* @param yggrasilConfigFile the config file.
* @throws YggdrasilException If an issue occurs during loading the configuration.
*/
public YggdrasilConfig(File yggrasilConfigFile) throws YggdrasilException {
ArgumentCheck.checkExistsNormalFile(yggrasilConfigFile, "File yggrasilConfigFile");
configdir = yggrasilConfigFile.getParentFile();
Map<String, LinkedHashMap> settings = YamlTools.loadYamlSettings(yggrasilConfigFile);
Map<String, Object> valuesMap = settings.get(RunningMode.getMode().toString());
databaseDir = extractConfigValueAsDirectory(valuesMap, DATABASE_DIR_PROPERTY, null);
tmpDir = extractConfigValueAsDirectory(valuesMap, TEMPORARY_DIR_PROPERTY, "temporarydir");
monitorPort = (Integer) extractConfigValue(valuesMap, MONITOR_PORT_PROPERTY, DEFAULT_MONITOR_PORT_PROPERTY);
warcSizeLimit = extractConfigLongValue(valuesMap, WARC_SIZE_LIMIT_PROPERTY, DEFAULT_WARC_SIZE_LIMIT);
uploadWaitLimit = extractConfigLongValue(valuesMap, UPLOAD_WAIT_LIMIT_PROPERTY, DEFAULT_UPLOAD_WAIT_LIMIT);
checkWarcConditionInterval = extractConfigLongValue(valuesMap, CHECK_WARC_CONDITION_INTERVAL_PROPERTY,
DEFAULT_CHECK_WARC_CONDITION_INTERVAL);
}
/**
* Extracts the configuration value for the given property.
* If the property has not been defined in the configuration, then the default value is used.
* @param configs The configuration map to extract the given configuration from.
* @param property The name of the configuration property.
* @param defaultValue The default value to use, if no value was defined in the configuration.
* @return The configuration value.
* @throws YggdrasilException If the configuration was not set, and it has no default value.
*/
private String extractConfigStringValue(Map<String, Object> configs, String property, String defaultValue)
throws YggdrasilException {
// TODO handle sub-maps.
String res = (String) configs.get(property);
if(res == null || res.isEmpty()) {
if(defaultValue == null || defaultValue.isEmpty()) {
throw new YggdrasilException("Undefined configuraion '" + property + "', and no default value.");
}
return defaultValue;
}
return res;
}
/**
* Extracts a configuration property as a Long, even though YAML claims it to be a Integer.
* @param configs The configuration map to extract the given configuration from.
* @param property The name of the configuration property.
* @param defaultValue The default value to use, if no value was defined in the configuration.
* @return The configuration value.
* @throws YggdrasilException If the configuration was not set, and it has no default value.
*/
private Long extractConfigLongValue(Map<String, Object> configs, String property, Object defaultValue)
throws YggdrasilException {
Object res = extractConfigValue(configs, property, defaultValue);
if(res.getClass() == Integer.class) {
int i = (Integer) res;
return Long.valueOf(i);
}
return (Long) res;
}
/**
* Extracts the configuration value for the given property.
* If the property has not been defined in the configuration, then the default value is used.
* @param configs The configuration map to extract the given configuration from.
* @param property The name of the configuration property.
* @param defaultValue The default value to use, if no value was defined in the configuration.
* @return The configuration value.
* @throws YggdrasilException If the configuration was not set, and it has no default value.
*/
private Object extractConfigValue(Map<String, Object> configs, String property, Object defaultValue)
throws YggdrasilException {
// TODO handle sub-maps.
Object res = configs.get(property);
if(res == null) {
if(defaultValue == null) {
throw new YggdrasilException("Undefined configuraion '" + property + "', and no default value.");
}
return defaultValue;
}
return res;
}
/**
* Instantiates a configuration property as a directory.
* @param configs The configuration map to extract the given configuration from.
* @param property The name of the configuration property.
* @param defaultValue The default value to use, if no value was defined in the configuration.
* @return The configuration value.
* @throws YggdrasilException If the configuration was not set, and it has no default value.
* Or if the directory path could not be instantiated as a directory.
*/
private File extractConfigValueAsDirectory(Map<String, Object> configs, String property, String defaultValue)
throws YggdrasilException {
File res = new File(extractConfigStringValue(configs, property, defaultValue));
if (!res.exists()) {
if (!res.mkdirs()) {
throw new YggdrasilException("Unable to create directory '" + res.getAbsolutePath()
+ "' from configuration '" + property + "'.");
}
}
if(!res.isDirectory()) {
throw new YggdrasilException("The configuration '" + property
+ "' cannot be instantiated as a directory.");
}
return res;
}
/**
* @return the database dir
*/
public File getDatabaseDir() {
return databaseDir;
}
/**
* @return the temporary directory
*/
public File getTemporaryDir() {
return tmpDir;
}
/**
* @return the config directory
*/
public File getConfigDir() {
return configdir;
}
/**
* @return the monitor port
*/
public int getMonitorPort() {
return monitorPort;
}
/**
* @return The warc size limit.
*/
public long getWarcSizeLimit() {
return warcSizeLimit;
}
/**
* @return The upload wait limit.
*/
public long getUploadWaitLimit() {
return uploadWaitLimit;
}
/**
* @return The interval for checking the warc conditions.
*/
public long getCheckWarcConditionInterval() {
return checkWarcConditionInterval;
}
}