[New] Allow to override DB config in env
This commit is contained in:
parent
405704968e
commit
8d8bfd0ede
|
@ -16,6 +16,7 @@
|
|||
package li.strolch.runtime;
|
||||
|
||||
import static li.strolch.utils.helper.StringHelper.DOT;
|
||||
import static li.strolch.utils.helper.StringHelper.UNDERLINE;
|
||||
|
||||
import li.strolch.agent.api.ObserverHandler;
|
||||
import li.strolch.model.StrolchModelConstants;
|
||||
|
@ -46,10 +47,14 @@ public class StrolchConstants extends StrolchModelConstants {
|
|||
public static final String TYPE_STROLCH_JOB = "StrolchJob";
|
||||
|
||||
public static String makeRealmKey(String realmName, String key) {
|
||||
return makeRealmKey(realmName, key, false);
|
||||
}
|
||||
|
||||
public static String makeRealmKey(String realmName, String key, boolean useEnv) {
|
||||
String realmKey = key;
|
||||
if (!realmName.equals(DEFAULT_REALM))
|
||||
realmKey += DOT + realmName;
|
||||
return realmKey;
|
||||
realmKey += (useEnv ? UNDERLINE : DOT) + realmName;
|
||||
return useEnv ? realmKey.replace(DOT, UNDERLINE).toUpperCase() : realmKey;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
package li.strolch.runtime.configuration;
|
||||
|
||||
import static li.strolch.db.DbConstants.*;
|
||||
import static li.strolch.runtime.StrolchConstants.DEFAULT_REALM;
|
||||
import static li.strolch.runtime.StrolchConstants.makeRealmKey;
|
||||
import static li.strolch.utils.helper.StringHelper.*;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
|
@ -29,7 +31,6 @@ import java.util.Set;
|
|||
import li.strolch.agent.api.ComponentContainer;
|
||||
import li.strolch.agent.api.StrolchRealm;
|
||||
import li.strolch.persistence.api.StrolchPersistenceException;
|
||||
import li.strolch.runtime.StrolchConstants;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -61,36 +62,44 @@ public abstract class DbConnectionBuilder {
|
|||
if (realm.getMode().isTransient())
|
||||
continue;
|
||||
|
||||
String dbIgnoreRealmKey = makeRealmKey(realmName, PROP_DB_IGNORE_REALM);
|
||||
String dbUrlKey = makeRealmKey(realmName, PROP_DB_URL);
|
||||
String dbUsernameKey = makeRealmKey(realmName, PROP_DB_USERNAME);
|
||||
String dbPasswordKey = makeRealmKey(realmName, PROP_DB_PASSWORD);
|
||||
String dbUseEnvKey = makeRealmKey(realmName, PROP_USE_ENV, false);
|
||||
boolean dbUseEnv = this.configuration.getBoolean(dbUseEnvKey, false);
|
||||
if (dbUseEnv)
|
||||
logger.info("Configuration specifies to use environment variables to configure DB access...");
|
||||
|
||||
boolean dbIgnoreRealm = this.configuration.getBoolean(dbIgnoreRealmKey, Boolean.FALSE);
|
||||
String dbUrlKey = makeRealmKey(realmName, PROP_DB_URL, dbUseEnv);
|
||||
String dbUsernameKey = makeRealmKey(realmName, PROP_DB_USERNAME, dbUseEnv);
|
||||
String dbPasswordKey = makeRealmKey(realmName, PROP_DB_PASSWORD, dbUseEnv);
|
||||
|
||||
String dbIgnoreRealmKey = makeRealmKey(realmName, PROP_DB_IGNORE_REALM, false);
|
||||
boolean dbIgnoreRealm = this.configuration.getBoolean(dbIgnoreRealmKey, false);
|
||||
if (dbIgnoreRealm) {
|
||||
logger.info("[" + realm + "] Ignoring any DB configuration for Realm " + realmName);
|
||||
continue;
|
||||
}
|
||||
|
||||
String dbUrl = this.configuration.getString(dbUrlKey, null);
|
||||
String username = this.configuration.getString(dbUsernameKey, null);
|
||||
String password = this.configuration.getString(dbPasswordKey, null);
|
||||
String dbUrl = getConfigString(dbUrlKey, dbUseEnv);
|
||||
String username = getConfigString(dbUsernameKey, dbUseEnv);
|
||||
String password = getConfigString(dbPasswordKey, dbUseEnv);
|
||||
|
||||
if (this.configuration.getBoolean(PROP_DB_ALLOW_HOST_OVERRIDE_ENV, false) //
|
||||
&& System.getProperties().containsKey(PROP_DB_HOST_OVERRIDE)) {
|
||||
dbUrl = overridePostgresqlHost(realm.getRealm(), dbUrl);
|
||||
dbUrl = overridePostgresqlHost(realm.getRealm(), dbUrl, dbUseEnv);
|
||||
}
|
||||
|
||||
// find any pool configuration values
|
||||
Set<String> propertyKeys = this.configuration.getPropertyKeys();
|
||||
Map<String, String> properties = dbUseEnv ? System.getenv() : this.configuration.getAsMap();
|
||||
String dbPoolPrefix = dbUseEnv ?
|
||||
PROP_DB_POOL_PREFIX.replace(DOT, UNDERLINE).toUpperCase() :
|
||||
PROP_DB_POOL_PREFIX;
|
||||
Properties props = new Properties();
|
||||
for (String key : propertyKeys) {
|
||||
if (!key.startsWith(PROP_DB_POOL_PREFIX))
|
||||
for (String key : properties.keySet()) {
|
||||
if (!key.startsWith(dbPoolPrefix))
|
||||
continue;
|
||||
|
||||
// TODO we should change how properties for realms are configured
|
||||
// since defaultRealm does not have to be on the key, we need this hack:
|
||||
String[] segments = key.split("\\.");
|
||||
String[] segments = key.split(dbUseEnv ? UNDERLINE : "\\.");
|
||||
String poolKey;
|
||||
String foundRealm;
|
||||
if (segments.length == 4) {
|
||||
|
@ -98,7 +107,7 @@ public abstract class DbConnectionBuilder {
|
|||
foundRealm = segments[3];
|
||||
} else if (segments.length == 3) {
|
||||
// default realm
|
||||
foundRealm = StrolchConstants.DEFAULT_REALM;
|
||||
foundRealm = DEFAULT_REALM;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Can't detect realm of this property: " + key);
|
||||
}
|
||||
|
@ -107,39 +116,62 @@ public abstract class DbConnectionBuilder {
|
|||
continue;
|
||||
|
||||
poolKey = segments[2];
|
||||
String value = this.configuration.getString(key, null);
|
||||
String value = properties.get(key);
|
||||
props.setProperty(poolKey, value);
|
||||
}
|
||||
|
||||
DataSource ds = build(realmName, dbUrl, username, password, props);
|
||||
|
||||
dsMap.put(realmName, ds);
|
||||
DataSource dataSource = build(realmName, dbUrl, username, password, props);
|
||||
dsMap.put(realmName, dataSource);
|
||||
}
|
||||
|
||||
return dsMap;
|
||||
}
|
||||
|
||||
public static String overridePostgresqlHost(String realm, String dbUrl) {
|
||||
if (!System.getProperties().containsKey(PROP_DB_HOST_OVERRIDE))
|
||||
return dbUrl;
|
||||
private String getConfigString(String dbKey, boolean useEnv) {
|
||||
if (!useEnv)
|
||||
return this.configuration.getString(dbKey, null);
|
||||
|
||||
String value = System.getenv(dbKey);
|
||||
if (isEmpty(value))
|
||||
throw new IllegalStateException("Missing environment variable " + dbKey);
|
||||
return value;
|
||||
}
|
||||
|
||||
public static String overridePostgresqlHost(String realmName, String dbUrl) {
|
||||
return overridePostgresqlHost(realmName, dbUrl, false);
|
||||
}
|
||||
|
||||
public static String overridePostgresqlHost(String realmName, String dbUrl, boolean useEnv) {
|
||||
String hostOverride;
|
||||
if (useEnv) {
|
||||
if (!System.getenv().containsKey(ENV_DB_HOST_OVERRIDE))
|
||||
return dbUrl;
|
||||
String hostOverrideKey = makeRealmKey(realmName, PROP_DB_HOST_OVERRIDE, true);
|
||||
hostOverride = System.getenv(hostOverrideKey);
|
||||
} else {
|
||||
if (!System.getProperties().containsKey(PROP_DB_HOST_OVERRIDE))
|
||||
return dbUrl;
|
||||
String hostOverrideKey = makeRealmKey(realmName, PROP_DB_HOST_OVERRIDE, false);
|
||||
hostOverride = System.getProperty(hostOverrideKey);
|
||||
}
|
||||
|
||||
if (!dbUrl.startsWith("jdbc:postgresql://"))
|
||||
throw new IllegalStateException("DB URL is invalid: " + dbUrl);
|
||||
|
||||
String tmp = dbUrl.substring("jdbc:postgresql://".length());
|
||||
String host = tmp.substring(0, tmp.indexOf('/'));
|
||||
String dbName = tmp.substring(tmp.indexOf('/'));
|
||||
String hostOverride = System.getProperty(PROP_DB_HOST_OVERRIDE);
|
||||
|
||||
if (host.equals(hostOverride))
|
||||
return dbUrl;
|
||||
|
||||
logger.warn("[" + realm + "] Replacing db host " + host + " with override " + hostOverride);
|
||||
logger.warn("[" + realmName + "] Replacing db host " + host + " with override " + hostOverride);
|
||||
dbUrl = "jdbc:postgresql://" + hostOverride + dbName;
|
||||
logger.warn("[" + realm + "] DB URL is now " + dbUrl);
|
||||
logger.warn("[" + realmName + "] DB URL is now " + dbUrl);
|
||||
return dbUrl;
|
||||
}
|
||||
|
||||
protected abstract DataSource build(String realm, String url, String username, String password, Properties proops);
|
||||
protected abstract DataSource build(String realm, String url, String username, String password, Properties props);
|
||||
|
||||
protected void validateConnection(DataSource ds) {
|
||||
try (Connection con = ds.getConnection()) {
|
||||
|
|
|
@ -91,7 +91,7 @@ public abstract class PostgreSqlInitializer extends SystemAction {
|
|||
|
||||
protected File getDataStoreFile(RuntimeConfiguration runtimeConfiguration,
|
||||
ComponentConfiguration realmConfiguration, String realmName) {
|
||||
String dataStoreKey = makeRealmKey(realmName, PREFIX_DATA_STORE_FILE);
|
||||
String dataStoreKey = makeRealmKey(realmName, PREFIX_DATA_STORE_FILE, false);
|
||||
return realmConfiguration.getDataFile(dataStoreKey, null, runtimeConfiguration, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
package li.strolch.persistence.xml;
|
||||
|
||||
import static li.strolch.agent.impl.DefaultRealmHandler.PREFIX_DATA_STORE_FILE;
|
||||
import static li.strolch.db.DbConstants.PROP_DB_IGNORE_REALM;
|
||||
import static li.strolch.db.DbConstants.PROP_USE_ENV;
|
||||
import static li.strolch.runtime.StrolchConstants.makeRealmKey;
|
||||
import static li.strolch.utils.helper.StringHelper.isEmpty;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.MessageFormat;
|
||||
|
@ -42,6 +45,7 @@ import li.strolch.runtime.configuration.ComponentConfiguration;
|
|||
import li.strolch.runtime.configuration.RuntimeConfiguration;
|
||||
import li.strolch.runtime.configuration.StrolchConfiguration;
|
||||
import li.strolch.runtime.configuration.StrolchConfigurationException;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
import li.strolch.xmlpers.api.*;
|
||||
|
||||
/**
|
||||
|
@ -79,18 +83,21 @@ public class XmlPersistenceHandler extends StrolchComponent implements Persisten
|
|||
if (realm.getMode().isTransient())
|
||||
continue;
|
||||
|
||||
String dbIgnoreRealmKey = makeRealmKey(realmName, PROP_DB_IGNORE_REALM);
|
||||
String dbStorePathKey = makeRealmKey(realmName, PROP_DB_STORE_PATH);
|
||||
String dbVerboseKey = makeRealmKey(realmName, PROP_VERBOSE);
|
||||
String dbUseEnvKey = makeRealmKey(realmName, PROP_USE_ENV, false);
|
||||
boolean dbUseEnv = configuration.getBoolean(dbUseEnvKey, false);
|
||||
|
||||
boolean dbIgnoreRealm = configuration.getBoolean(dbIgnoreRealmKey, Boolean.FALSE);
|
||||
String dbStorePathKey = makeRealmKey(realmName, PROP_DB_STORE_PATH, dbUseEnv);
|
||||
String dbVerboseKey = makeRealmKey(realmName, PROP_VERBOSE, dbUseEnv);
|
||||
|
||||
String dbIgnoreRealmKey = makeRealmKey(realmName, PROP_DB_IGNORE_REALM, false);
|
||||
boolean dbIgnoreRealm = configuration.getBoolean(dbIgnoreRealmKey, false);
|
||||
if (dbIgnoreRealm) {
|
||||
logger.info("Ignoring any DB configuration for Realm " + realmName);
|
||||
continue;
|
||||
}
|
||||
|
||||
String dbStorePath = configuration.getString(dbStorePathKey, null);
|
||||
boolean verbose = configuration.getBoolean(dbVerboseKey, Boolean.FALSE);
|
||||
String dbStorePath = getConfigString(configuration, dbStorePathKey, dbUseEnv);
|
||||
boolean verbose = getConfigBoolean(configuration, dbVerboseKey, dbUseEnv);
|
||||
|
||||
// validate URL
|
||||
if (dbStorePaths.contains(dbStorePath))
|
||||
|
@ -128,6 +135,26 @@ public class XmlPersistenceHandler extends StrolchComponent implements Persisten
|
|||
super.initialize(configuration);
|
||||
}
|
||||
|
||||
private String getConfigString(ComponentConfiguration configuration, String dbKey, boolean useEnv) {
|
||||
if (!useEnv)
|
||||
return configuration.getString(dbKey, null);
|
||||
|
||||
String value = System.getenv(dbKey);
|
||||
if (isEmpty(value))
|
||||
throw new IllegalStateException("Missing environment variable " + dbKey);
|
||||
return value;
|
||||
}
|
||||
|
||||
private Boolean getConfigBoolean(ComponentConfiguration configuration, String dbKey, boolean useEnv) {
|
||||
if (!useEnv)
|
||||
return configuration.getBoolean(dbKey, false);
|
||||
|
||||
String value = System.getenv(dbKey);
|
||||
if (isEmpty(value))
|
||||
throw new IllegalStateException("Missing environment variable " + dbKey);
|
||||
return StringHelper.parseBoolean(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws Exception {
|
||||
|
||||
|
|
|
@ -35,4 +35,6 @@ public class DbConstants {
|
|||
public static final String PROP_ALLOW_DATA_INIT_ON_EMPTY_DB = "allowDataInitOnEmptyDb";
|
||||
public static final String PROP_DB_VERSION = "db_version";
|
||||
public static final String RESOURCE_DB_VERSION = "/{0}_db_version.properties";
|
||||
|
||||
public static final String ENV_DB_HOST_OVERRIDE = "DB_HOST_OVERRIDE";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue