package org.arquillian.cube.docker.impl.docker.compose;
import static org.arquillian.cube.docker.impl.util.YamlUtil.asMap;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.arquillian.cube.docker.impl.client.Converter;
import org.arquillian.cube.docker.impl.client.config.CubeContainer;
import org.arquillian.cube.docker.impl.client.config.DockerCompositions;
import org.arquillian.cube.impl.util.IOUtil;
import org.yaml.snakeyaml.Yaml;
public class DockerComposeConverter implements Converter {
private static final String DOCKER_COMPOSE_VERSION_KEY = "version";
public static final String DOCKER_COMPOSE_VERSION_2_VALUE = "2";
private Map<String, Object> dockerComposeDefinitionMap = new HashMap<>();
private Path dockerComposeRootDirectory;
private DockerComposeConverter(Path location) throws IOException {
try (FileInputStream inputStream = new FileInputStream(location.toFile())) {
String content = DockerComposeEnvironmentVarResolver.replaceParameters(inputStream);
this.dockerComposeDefinitionMap = loadConfig(content);
this.dockerComposeRootDirectory = location.getParent();
}
}
private String resolvePlaceholders(String content) {
content = resolveSystemProperties(content);
final Map<String, String> env = System.getenv();
return IOUtil.replacePlaceholdersWithWhiteSpace(content, env);
}
private String resolveSystemProperties(String content) {
return IOUtil.replacePlaceholdersWithWhiteSpace(content);
}
private DockerComposeConverter(String content) {
String resolvePlaceholders = resolvePlaceholders(content);
this.dockerComposeDefinitionMap = loadConfig(resolvePlaceholders);
this.dockerComposeRootDirectory = Paths.get(".");
}
public static DockerComposeConverter create(Path location) {
try {
return new DockerComposeConverter(location);
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
public static DockerComposeConverter create(String content) {
return new DockerComposeConverter(content);
}
public DockerCompositions convert() {
DockerCompositions dockerCompositions = new DockerCompositions();
Set<String> names = dockerComposeDefinitionMap.keySet();
boolean isV2 = names.contains(DOCKER_COMPOSE_VERSION_KEY) && DOCKER_COMPOSE_VERSION_2_VALUE.equals(dockerComposeDefinitionMap.get(DOCKER_COMPOSE_VERSION_KEY));
if (isV2) {
dockerCompositions = convertCompose(dockerComposeDefinitionMap);
} else {
for(String name : names) {
CubeContainer cubeContainer = convertContainer(asMap(dockerComposeDefinitionMap, name));
if (cubeContainer.getContainerName() != null) {
dockerCompositions.add(cubeContainer.getContainerName(), cubeContainer);
} else {
dockerCompositions.add(name, cubeContainer);
}
}
}
return dockerCompositions;
}
private DockerCompositions convertCompose(Map<String, Object> dockerComposeContainerDefinition) {
ComposeBuilder composeBuilder = new ComposeBuilder(this.dockerComposeRootDirectory);
return composeBuilder.build(dockerComposeContainerDefinition);
}
private CubeContainer convertContainer(Map<String, Object> dockerComposeContainerDefinition) {
ContainerBuilder containerBuilder = new ContainerBuilder(this.dockerComposeRootDirectory);
return containerBuilder.build(dockerComposeContainerDefinition);
}
@SuppressWarnings("unchecked")
private Map<String, Object> loadConfig(String content) {
return (Map<String, Object>) new Yaml().load(content);
}
}