001package io.ebean.docker.commands; 002 003import io.ebean.docker.container.ContainerConfig; 004 005import java.sql.Connection; 006import java.sql.SQLException; 007import java.util.Properties; 008 009/** 010 * Configuration for an DBMS like Postgres, MySql, Oracle, SQLServer 011 */ 012public abstract class BaseConfig implements ContainerConfig { 013 014 /** 015 * The database platform. 016 * <p> 017 * Expected to be one of 'postgres','mysql', 'oracle' or 'sqlserver'. 018 */ 019 protected final String platform; 020 021 /** 022 * Container name. 023 */ 024 protected String containerName; 025 026 /** 027 * The exposed port. 028 */ 029 protected int port; 030 031 /** 032 * The internal port. 033 */ 034 protected int internalPort; 035 036 /** 037 * The exposed port. 038 */ 039 protected int adminPort; 040 041 /** 042 * The internal port. 043 */ 044 protected int adminInternalPort; 045 046 /** 047 * Image name. 048 */ 049 protected String image; 050 051 /** 052 * The mode used when starting (create, dropCreate, container [only]). 053 */ 054 protected StartMode startMode = StartMode.Create; 055 056 /** 057 * The mode used when stopping (stop, remove). 058 */ 059 protected StopMode stopMode = StopMode.Stop; 060 061 /** 062 * Set when we want to automatically stop or remove the container via JVM shutdown hook. 063 */ 064 protected StopMode shutdownMode = StopMode.None; 065 066 /** 067 * The character set to use. 068 */ 069 protected String characterSet; 070 071 /** 072 * The collation to use. 073 */ 074 protected String collation; 075 076 /** 077 * Maximum number of attempts to find the 'database ready to accept connections' log message in the container. 078 * <p> 079 * 100 attempts equates to 10 seconds. 080 * </p> 081 */ 082 protected int maxReadyAttempts = 300; 083 084 /** 085 * Docker command. 086 */ 087 protected String docker = "docker"; 088 089 protected final String version; 090 091 BaseConfig(String platform, int port, int internalPort, String version) { 092 this.platform = platform; 093 this.port = port; 094 this.internalPort = internalPort; 095 this.containerName = "ut_" + platform; 096 this.image = platform + ":" + version; 097 this.version = version; 098 } 099 100 /** 101 * Return a description of the configuration. 102 */ 103 @Override 104 public String startDescription() { 105 return "starting " + platform + " container:" + containerName + " port:" + port + " startMode:" + startMode; 106 } 107 108 @Override 109 public String stopDescription() { 110 return "stopping " + platform + " container:" + containerName + " stopMode:" + stopMode; 111 } 112 113 @Override 114 public String platform() { 115 return platform; 116 } 117 118 @Override 119 public String containerName() { 120 return containerName; 121 } 122 123 @Override 124 public String version() { 125 return version; 126 } 127 128 @Override 129 public void setStartMode(StartMode startMode) { 130 this.startMode = startMode; 131 } 132 133 @Override 134 public void setStopMode(StopMode stopMode) { 135 this.stopMode = stopMode; 136 } 137 138 @Override 139 public void setShutdownMode(StopMode shutdownMode) { 140 this.shutdownMode = shutdownMode; 141 } 142 143 /** 144 * Return a Connection to the database (make sure you close it). 145 */ 146 @Override 147 public Connection createConnection() throws SQLException { 148 throw new IllegalStateException("Not valid for this type"); 149 } 150 151 @Override 152 public Connection createConnectionNoSchema() throws SQLException { 153 throw new IllegalStateException("Not valid for this type"); 154 } 155 156 @Override 157 public Connection createAdminConnection() throws SQLException { 158 throw new IllegalStateException("Not valid for this type"); 159 } 160 161 @Override 162 public String jdbcUrl() { 163 throw new IllegalStateException("Not valid for this type"); 164 } 165 166 @Override 167 public String jdbcAdminUrl() { 168 return jdbcUrl(); 169 } 170 171 /** 172 * Load configuration from properties. 173 */ 174 public BaseConfig setProperties(Properties properties) { 175 if (properties == null) { 176 return this; 177 } 178 docker = properties.getProperty("docker", docker); 179 180 containerName = prop(properties, "containerName", containerName); 181 image = prop(properties, "image", image); 182 port = prop(properties, "port", port); 183 internalPort = prop(properties, "internalPort", internalPort); 184 adminPort = prop(properties, "adminPort", adminPort); 185 adminInternalPort = prop(properties, "adminInternalPort", adminInternalPort); 186 characterSet = prop(properties, "characterSet", characterSet); 187 collation = prop(properties, "collation", collation); 188 189 String start = properties.getProperty("startMode", startMode.name()); 190 startMode = StartMode.of(prop(properties, "startMode", start)); 191 192 String stop = properties.getProperty("stopMode", stopMode.name()); 193 stopMode = StopMode.of(prop(properties, "stopMode", stop)); 194 195 String shutdown = properties.getProperty("shutdown", shutdownMode.name()); 196 shutdownMode = StopMode.of(prop(properties, "shutdown", shutdown)); 197 198 String maxVal = prop(properties, "maxReadyAttempts", null); 199 if (maxVal != null) { 200 try { 201 this.maxReadyAttempts = Integer.parseInt(maxVal); 202 } catch (NumberFormatException e) { 203 // ignore error 204 } 205 } 206 return this; 207 } 208 209 protected String prop(Properties properties, String key, String defaultValue) { 210 String val = properties.getProperty("ebean.test." + platform + "." + key, defaultValue); 211 return properties.getProperty(platform + "." + key, val); 212 } 213 214 protected int prop(Properties properties, String key, int defaultValue) { 215 String val = properties.getProperty("ebean.test." + platform + "." + key); 216 val = properties.getProperty(platform + "." + key, val); 217 return val == null ? defaultValue : Integer.parseInt(val); 218 } 219 220 /** 221 * Set the container name. 222 */ 223 public BaseConfig setContainerName(String containerName) { 224 this.containerName = containerName; 225 return this; 226 } 227 228 /** 229 * Set the exposed port. 230 */ 231 public BaseConfig setPort(int port) { 232 this.port = port; 233 return this; 234 } 235 236 /** 237 * Set the internal (to the container) port. 238 */ 239 public BaseConfig setInternalPort(int internalPort) { 240 this.internalPort = internalPort; 241 return this; 242 } 243 244 /** 245 * Set the exposed admin port. 246 */ 247 public BaseConfig setAdminPort(int adminPort) { 248 this.adminPort = adminPort; 249 return this; 250 } 251 252 /** 253 * Set the internal admin (to the container) port. 254 */ 255 public BaseConfig setAdminInternalPort(int adminInternalPort) { 256 this.adminInternalPort = adminInternalPort; 257 return this; 258 } 259 260 /** 261 * Set the docker image to use. 262 */ 263 public BaseConfig setImage(String image) { 264 this.image = image; 265 return this; 266 } 267 268 /** 269 * Set the character set to use. 270 */ 271 public BaseConfig setCharacterSet(String characterSet) { 272 this.characterSet = characterSet; 273 return this; 274 } 275 276 /** 277 * Set the collation to use. 278 */ 279 public BaseConfig setCollation(String collation) { 280 this.collation = collation; 281 return this; 282 } 283 284 /** 285 * Set the max attempts to wait for DB ready. 286 */ 287 public BaseConfig setMaxReadyAttempts(int maxReadyAttempts) { 288 this.maxReadyAttempts = maxReadyAttempts; 289 return this; 290 } 291 292 /** 293 * Set the docker command to use (defaults to 'docker'). 294 */ 295 public BaseConfig setDocker(String docker) { 296 this.docker = docker; 297 return this; 298 } 299 300 public int getPort() { 301 return port; 302 } 303 304 public int getInternalPort() { 305 return internalPort; 306 } 307 308 public int getAdminPort() { 309 return adminPort; 310 } 311 312 public int getAdminInternalPort() { 313 return adminInternalPort; 314 } 315 316 public String getImage() { 317 return image; 318 } 319 320 public StartMode getStartMode() { 321 return startMode; 322 } 323 324 public StopMode getStopMode() { 325 return stopMode; 326 } 327 328 public int getMaxReadyAttempts() { 329 return maxReadyAttempts; 330 } 331 332 public String getDocker() { 333 return docker; 334 } 335 336 public StopMode shutdownMode() { 337 return shutdownMode; 338 } 339 340 public String getCharacterSet() { 341 return characterSet; 342 } 343 344 public String getCollation() { 345 return collation; 346 } 347 348 public boolean isExplicitCollation() { 349 return collation != null || characterSet != null; 350 } 351 352 public boolean isDefaultCollation() { 353 return "default".equals(collation); 354 } 355 356 public boolean isStopModeNone() { 357 return StopMode.None == stopMode; 358 } 359 360 /** 361 * Clear the stopMode when detect already running. 362 */ 363 public void clearStopMode() { 364 this.stopMode = StopMode.None; 365 } 366}