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