package eu.esdihumboldt.hale.common.test.docker.config;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
/**
* A docker config class which is responsible for getting the docker
* configuration information. It searches for the configuration in System
* properties, working directory, home directory and classpath.
* <p>
* <strong>Example </strong></br> Mandatory configurations are:
* <ul>
* <li>dockerHost</li>
* <li>dockerImage</>
* </ul>
* </br>Optional configuration are:
* <ul>
* <li>exposedPorts (default: exposed ports in the image, if mentioned then it
* will be added to the image's exposed port list )</li>
* <li>exposeAllPorts (default: true, while starting a container, if all ports
* to be exposed for providing services outside the container.) This should be
* true to start the communication with the container from HALE.</>
* <li>command (default: commands used in the image will be used)</>
* <li>isPrivileged (default: false)</>
* </ul>
*
* The docker configuration example is as below:
*
* <pre>
* dockertest{
* dockerHost="http://192.168.59.103:2375"
* dockerImage="stempler/postgis" // "kartoza/postgis"
* exposeAllPorts=true
* exposedPorts=["5432/tcp"]
* command=["/start-postgis.sh"]
* isPrivileged=false
*
* }
* </pre>
*
* <p>
* <h2>Preference order</h2>
* Hale looks for the docker configuration in the following files in the
* following order:
* <ul>
* <li>System.getProperty("docker.conf.file")</li>
* <li>HOMEDIR/.hale/hale-docker.conf</li>
* <li>WORKDIR/hale-docker.conf</li>
* <li>CLASSPATH/hale-docker.conf</li>
* </ul>
*
* Configuration in home directory takes precedence over configuration in
* working directory. That means, user can override the configuration with the
* updated one without changing project setup.
* <p>
* <strong>Global configuration </strong> Hale gives more precedence to the
* global docker host configuration than the embedded one. <strong> Example
* </strong> </br></br> global{</br> dockerHost="http://192.168.59.103:2375"
* </br>}</br></br> takes more precedence over </br></br> postgis{</br>
* dockerHost="http://127.0.0.1:2375"</br> }
*
*
*
* @author Sameer Sheikh
*
*/
public class DockerConfig {
/**
* Docker configuration file key
*/
public static final String DOCKER_CONF = "hale-docker.conf";
/**
* docker configuration directory key
*/
public static final String DOCKER_CONF_DIR = ".hale";
/**
* docker conf file (for configuration set on system property.
*/
public static final String DOCKER_CONF_FILE = "docker.conf.file";
/**
* Looks for the configuration file in the home directory
*
* @return the absolute path of the configuration file in the home directory
*/
private static String getHomeDirConf() {
return new File(new File(System.getProperty("user.home"), DOCKER_CONF_DIR), DOCKER_CONF)
.getAbsolutePath();
}
/**
* Looks for the configuration file in the working directory
*
* @return the absolute path of the configuration file in the working
* directory
*/
private static String getWorkDirConf() {
return new File(System.getProperty("user.dir"), DOCKER_CONF).getAbsolutePath();
}
/**
* Checks for the configuration file in the system properties, home
* directory, working directory and then class path.
*
* @param cl a class loader to fetch the configuration from class path
*
* @return A config object which maps configuration keys to configuration
* values.
*/
public static Config getDockerConfig(ClassLoader cl) {
return ConfigFactory.systemProperties()
.withFallback(loadConfigFromPath(System.getProperty(DOCKER_CONF_FILE)))
.withFallback(loadConfigFromPath(getHomeDirConf()))
.withFallback(loadConfigFromPath(getWorkDirConf()))
.withFallback(loadConfigFromClassPath(cl)).resolve();
}
/**
* gets the configuration file from the class path.
*
* @param cl a class loader to fetch the configuration from class path
*
* @return config object which maps config key to config value
*/
private static Config loadConfigFromClassPath(ClassLoader cl) {
InputStream is = cl.getResourceAsStream(DOCKER_CONF);
if (is == null)
return ConfigFactory.empty();
else
return ConfigFactory.parseReader(new InputStreamReader(is));
}
/**
* loads the config from the given path
*
* @param path config path
* @return config which maps config key to config value
*/
private static Config loadConfigFromPath(String path) {
if (path == null) {
return ConfigFactory.empty();
}
File f = new File(path);
if (!f.exists()) {
return ConfigFactory.empty();
}
return ConfigFactory.parseFile(f);
}
}