/*
* Copyright (C) 2014 Intel Corporation
* All rights reserved.
*/
package com.intel.mtwilson.fs;
import com.intel.dcsg.cpg.io.AllCapsEnvironmentConfiguration;
import com.intel.dcsg.cpg.io.Platform;
import com.intel.dcsg.cpg.validation.ValidationUtil;
import java.io.File;
import java.util.HashMap;
import java.util.Properties;
import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.SystemConfiguration;
import org.apache.commons.configuration.EnvironmentConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.MapConfiguration;
/**
*
* @author jbuhacoff
*/
public class ConfigurableFilesystem extends AbstractFilesystem {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ConfigurableFilesystem.class);
public final String FILESYSTEM_NAME = "fs.name"; // to change filesystem root from /opt/mtwilson to /opt/trustagent, run java -Dfs.name=trustagent or export FS_NAME=trustagent before running java
public final String FILESYSTEM_ROOT_PATH = "fs.root"; // to change filesystem root from /opt/mtwilson to /usr/share/mtwilson, run java -Dfs.root=/usr/share
public final String FILESYSTEM_APPLICATION_PATH = "fs.home"; // to change filesystem root from /opt/mtwilson to /opt/trustagent, run java -Dfs.root=/opt/trustagent
public final String FILESYSTEM_CONFIGURATION_PATH = "fs.conf"; // to change configuration folder from /opt/mtwilson/configuration to /opt/trustagent/configuration, just set -Dfs.name (above); but to set it to /etc/mtwilson run java -Dfs.conf=/etc/mtwilson or to /etc/trustagent -Dfs.conf=/etc/trustagent
public final String FILESYSTEM_ENVIRONMENT_PATH = "fs.env"; // to change configuration folder from /opt/mtwilson/env.d to /etc/sysconfig/mtwilson, just set -Dfs.env=/etc/sysconfig/mtwilson
private Configuration configuration;
private PlatformFilesystem platformFilesystem;
public ConfigurableFilesystem() {
this(new MapConfiguration(new Properties()));
}
/**
* First priority is the configuration that is passed in.
* Second is the java system properties specified on command line like -Dfs.name
* Third is exported environment variables like FS_NAME
*
* @param configuration
*/
public ConfigurableFilesystem(Configuration configuration) {
CompositeConfiguration composite = new CompositeConfiguration();
composite.addConfiguration(configuration);
SystemConfiguration system = new SystemConfiguration();
composite.addConfiguration(system);
EnvironmentConfiguration env = new EnvironmentConfiguration();
composite.addConfiguration(env);
AllCapsEnvironmentConfiguration envAllCaps = new AllCapsEnvironmentConfiguration();
composite.addConfiguration(envAllCaps);
this.configuration = composite;
}
@Override
protected String getApplicationName() {
// log.debug("configured {} = {}", FILESYSTEM_NAME, getString(FILESYSTEM_NAME));
return getString(FILESYSTEM_NAME, "mtwilson");
}
@Override
protected PlatformFilesystem getPlatformFilesystem() {
if( platformFilesystem == null ) {
String root = getString(FILESYSTEM_ROOT_PATH, null);
// log.debug("configured {} = {}", FILESYSTEM_ROOT_PATH, getString(FILESYSTEM_ROOT_PATH));
if( root != null ) {
platformFilesystem = new RelativeFilesystem(root);
}
else {
platformFilesystem = super.getPlatformFilesystem();
}
}
return platformFilesystem;
}
/**
* If a user has set an environment variable {@code FS_HOME=/usr/share}
* and then unsets it with @{code FS_HOME=} instead of {@code unset FS_HOME}
* then FS_HOME will really be set to empty string and all the paths
* will come out "wrong". This wrapper around configuration's getString
* ensures that we use default values whenever the setting is null or empty.
* @param key
* @param defaultValue may be a value, empty string, or null depending on what you want to get when the configuration does not have a non-empty value for the key
* @return
*/
private String getString(String key, String defaultValue) {
String value = configuration.getString(key);
if( value == null || value.isEmpty() ) {
return defaultValue;
}
return value;
}
@Override
public String getApplicationPath() {
// log.debug("configured {} = {}", FILESYSTEM_APPLICATION_PATH, getString(FILESYSTEM_APPLICATION_PATH));
return getString(FILESYSTEM_APPLICATION_PATH, super.getApplicationPath());
}
@Override
public String getConfigurationPath() {
// log.debug("configured {} = {}", FILESYSTEM_CONFIGURATION_PATH, getString(FILESYSTEM_CONFIGURATION_PATH));
return getString(FILESYSTEM_CONFIGURATION_PATH, super.getConfigurationPath());
}
@Override
public String getEnvironmentExtPath() {
return getString(FILESYSTEM_ENVIRONMENT_PATH, super.getEnvironmentExtPath());
}
@Override
public FeatureFilesystem getBootstrapFilesystem() {
// return new BasicFeatureFilesystem(getApplicationPath());
HashMap<String,Object> map = new HashMap<>();
map.put("fs.feature.root", getApplicationPath());
map.put("fs.feature.java", getString("fs.java", getApplicationPath() + File.separator + "java"));
map.put("fs.feature.hypertext", getString("fs.hypertext", getApplicationPath() + File.separator + "hypertext"));
map.put("fs.feature.license_d", getString("fs.license_d", getApplicationPath() + File.separator + "license.d"));
map.put("fs.feature.sql", getString("fs.sql", getApplicationPath() + File.separator + "sql"));
map.put("fs.feature.bin", getString("fs.bin", getApplicationPath() + File.separator + "bin"));
map.put("fs.feature.var", getString("fs.var", getApplicationPath() + File.separator + "var"));
ConfigurableFeatureFilesystem featureFilesystem = new ConfigurableFeatureFilesystem(new MapConfiguration(map));
return featureFilesystem;
}
@Override
public FeatureFilesystem getFeatureFilesystem(String featureId) {
if( !ValidationUtil.isValidWithRegex(featureId, FilesystemUtil.FEATURE_ID_REGEX) ) { throw new IllegalArgumentException("Invalid feature id"); } // must start with a letter, then it can have letters, digits, underscores, dots, and hyphens, but not two dots in a row, and must end with a letter or digit
return new BasicFeatureFilesystem( getApplicationPath() + File.separator + "features" + File.separator + featureId );
}
}