001package io.ebean.docker.container; 002 003import io.ebean.docker.commands.ClickHouseContainer; 004import io.ebean.docker.commands.CockroachContainer; 005import io.ebean.docker.commands.ElasticContainer; 006import io.ebean.docker.commands.HanaContainer; 007import io.ebean.docker.commands.MariaDBContainer; 008import io.ebean.docker.commands.MySqlContainer; 009import io.ebean.docker.commands.NuoDBContainer; 010import io.ebean.docker.commands.OracleContainer; 011import io.ebean.docker.commands.PostgresContainer; 012import io.ebean.docker.commands.RedisContainer; 013import io.ebean.docker.commands.SqlServerContainer; 014 015import java.util.ArrayList; 016import java.util.HashSet; 017import java.util.List; 018import java.util.Properties; 019import java.util.Set; 020import java.util.function.Consumer; 021 022/** 023 * Creates containers from properties with the ability to start and stop them. 024 */ 025public class ContainerFactory { 026 027 private final Properties properties; 028 029 private final List<Container> containers = new ArrayList<>(); 030 031 private final Set<String> runWith = new HashSet<>(); 032 033 private static String defaultRunWith() { 034 String runWith = System.getenv("DOCKER_RUN_WITH"); 035 return System.getProperty("docker_run_with", runWith); 036 } 037 038 /** 039 * Create given properties and reading system and env properties for 'run with'. 040 */ 041 public ContainerFactory(Properties properties) { 042 this(properties, defaultRunWith()); 043 } 044 045 /** 046 * Create given the properties and runWith. 047 * 048 * @param properties The properties to configure the containers 049 * @param runWith Comma delimited string with container to run 050 */ 051 public ContainerFactory(Properties properties, String runWith) { 052 this.properties = properties; 053 initRunWith(runWith); 054 init(); 055 } 056 057 private void initRunWith(String runWithOptions) { 058 if (runWithOptions != null) { 059 for (String value : runWithOptions.split(",")) { 060 runWith.add(value.trim().toLowerCase()); 061 } 062 } 063 } 064 065 private void init() { 066 String elasticVersion = version("elastic"); 067 if (elasticVersion != null) { 068 containers.add(ElasticContainer.create(elasticVersion, properties)); 069 } 070 String redisVersion = version("redis"); 071 if (redisVersion != null) { 072 containers.add(RedisContainer.create(redisVersion, properties)); 073 } 074 String pgVersion = runWithVersion("postgres"); 075 if (pgVersion != null) { 076 containers.add(PostgresContainer.create(pgVersion, properties)); 077 } 078 String mysqlVersion = runWithVersion("mysql"); 079 if (mysqlVersion != null) { 080 containers.add(MySqlContainer.create(mysqlVersion, properties)); 081 } 082 String mariadbVersion = runWithVersion("mariadb"); 083 if (mariadbVersion != null) { 084 containers.add(MariaDBContainer.create(mariadbVersion, properties)); 085 } 086 String nuodbVersion = runWithVersion("nuodb"); 087 if (nuodbVersion != null) { 088 containers.add(NuoDBContainer.create(nuodbVersion, properties)); 089 } 090 String sqlServerVersion = runWithVersion("sqlserver"); 091 if (sqlServerVersion != null) { 092 containers.add(SqlServerContainer.create(sqlServerVersion, properties)); 093 } 094 String oracleVersion = runWithVersion("oracle"); 095 if (oracleVersion != null) { 096 containers.add(OracleContainer.create(oracleVersion, properties)); 097 } 098 String hanaVersion = runWithVersion("hana"); 099 if (hanaVersion != null) { 100 containers.add(HanaContainer.create(hanaVersion, properties)); 101 } 102 String clickhouseVersion = runWithVersion("clickhouse"); 103 if (clickhouseVersion != null) { 104 containers.add(ClickHouseContainer.create(clickhouseVersion, properties)); 105 } 106 String cockroachVersion = runWithVersion("cockroach"); 107 if (cockroachVersion != null) { 108 containers.add(CockroachContainer.create(cockroachVersion, properties)); 109 } 110 } 111 112 /** 113 * Return the version if the container should be added. 114 * Filters out database containers using <code>runWith</code>. 115 */ 116 String runWithVersion(String name) { 117 String version = version(name); 118 if (version == null) { 119 return null; 120 } 121 return (runWith.isEmpty() || runWith.contains(name)) ? version : null; 122 } 123 124 private String version(String prefix) { 125 return properties.getProperty(prefix + ".version"); 126 } 127 128 /** 129 * Start all the containers. 130 */ 131 public void startContainers() { 132 startContainers(null); 133 } 134 135 /** 136 * Start all the containers with a consumer for logging start descriptions. 137 */ 138 public void startContainers(Consumer<String> logging) { 139 for (Container container : containers) { 140 if (logging != null) { 141 logging.accept(container.config().startDescription()); 142 } 143 container.start(); 144 } 145 } 146 147 /** 148 * Stop all containers using the stopMode which defaults to also removing the containers. 149 */ 150 public void stopContainers() { 151 stopContainers(null); 152 } 153 154 /** 155 * Stop all the containers with a consumer for logging stop descriptions. 156 */ 157 public void stopContainers(Consumer<String> logging) { 158 159 for (Container container : containers) { 160 if (logging != null) { 161 logging.accept(container.config().stopDescription()); 162 } 163 container.stop(); 164 } 165 } 166 167 /** 168 * Stop all containers (without removing the containers). 169 */ 170 public void stopOnly() { 171 stopOnly(null); 172 } 173 174 /** 175 * Stop all the containers (without remove) with a consumer for logging stop descriptions. 176 */ 177 public void stopOnly(Consumer<String> logging) { 178 179 for (Container container : containers) { 180 if (logging != null) { 181 logging.accept(container.config().stopDescription()); 182 } 183 container.stopOnly(); 184 } 185 } 186 187 /** 188 * Return the config for a given platform. 189 */ 190 public ContainerConfig config(String platform) { 191 Container container = container(platform); 192 return (container == null) ? null : container.config(); 193 } 194 195 /** 196 * Return the container for a given platform. 197 */ 198 public Container container(String platform) { 199 for (Container container : containers) { 200 ContainerConfig config = container.config(); 201 if (config.platform().equalsIgnoreCase(platform)) { 202 return container; 203 } 204 } 205 return null; 206 } 207}