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); } }