From 79980295594aa1339839f219e999280ab4d586e9 Mon Sep 17 00:00:00 2001 From: Jonathan Austin Date: Thu, 26 Mar 2020 13:09:32 +1100 Subject: [PATCH 01/11] Latest qa-parent --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1bc31bf..4e6a47c 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.bordertech.common qa-parent - 1.0.15 + 1.0.16 jar From b82706bfc6c75f08f6536a574750c33460910164 Mon Sep 17 00:00:00 2001 From: Jonathan Austin Date: Thu, 26 Mar 2020 13:11:26 +1100 Subject: [PATCH 02/11] Allow override of default config file name --- .../github/bordertech/config/InitHelper.java | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/bordertech/config/InitHelper.java b/src/main/java/com/github/bordertech/config/InitHelper.java index 921f87f..2f6ceef 100644 --- a/src/main/java/com/github/bordertech/config/InitHelper.java +++ b/src/main/java/com/github/bordertech/config/InitHelper.java @@ -6,10 +6,17 @@ import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.ConfigurationUtils; import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.lang3.StringUtils; /** * Helper class for {@link Config} initialisation. *

+ * The helper checks for configuration overrides by searching for a property file named + * bordertech-config.properties in the user home directory, the current classpath and the system classpath. + * The file name can be overridden by setting an environment or system property with the key + * bordertech.config.file. + *

+ *

* The following properties can be set:- *

*

* The default resources Config looks for are:- @@ -33,6 +37,10 @@ *

  • bordertech-local.properties - local developer properties
  • * * + *

    + * Resources are ordered lowest to highest priority in determining which property value is used if property keys are + * duplicated. + *

    * * @author Jonathan Austin * @since 1.0.0 @@ -47,6 +55,7 @@ public final class InitHelper { private static final String PARAM_KEY_SPI_ENABLED = "bordertech.config.spi.enabled"; private static final String PARAM_KEY_SPI_APPEND_DEFAULT = "bordertech.config.spi.append.default"; private static final String PARAM_KEY_RESOURCE_ORDER = "bordertech.config.resource.order"; + private static final String PARAM_KEY_RESOURCE_APPEND = "bordertech.config.resource.append"; private static final List DEFAULT_BORDERTECH_LOAD_ORDER = Arrays.asList( // The name of the first resource we look for is for internal default properties "bordertech-defaults.properties", @@ -73,15 +82,13 @@ public final class InitHelper { // Load the config defaults (if exists) String configFile = getDefaultConfigFileName(); Configuration configDefaults = loadPropertyFile(configFile); + // Default config impl DEFAULT_CONFIG_IMPL = configDefaults.getString(PARAM_KEY_DEFAULT_CONFIG_IMPL, DefaultConfiguration.class.getName()); + // Check if SPI enabled SPI_APPEND_DEFAULT_CONFIG = configDefaults.getBoolean(PARAM_KEY_SPI_APPEND_DEFAULT, true); SPI_ENABLED = configDefaults.getBoolean(PARAM_KEY_SPI_ENABLED, true); - String[] override = configDefaults.getStringArray(PARAM_KEY_RESOURCE_ORDER); - if (override == null || override.length == 0) { - DEFAULT_RESOURCE_LOAD_ORDER = DEFAULT_BORDERTECH_LOAD_ORDER; - } else { - DEFAULT_RESOURCE_LOAD_ORDER = Arrays.asList(override); - } + // Load resource order + DEFAULT_RESOURCE_LOAD_ORDER = getResourceOrder(configDefaults); } /** @@ -143,4 +150,27 @@ private static String getDefaultConfigFileName() { return StringUtils.isBlank(name) ? DEFAULTS_FILE_NAME : name; } + /** + * Retrieve the resource order. + * + * @param configDefaults the config defaults + * @return the list of resources in load order + */ + private static List getResourceOrder(final Configuration configDefaults) { + List resources = new ArrayList<>(); + // Check for default resource overrides + String[] override = configDefaults.getStringArray(PARAM_KEY_RESOURCE_ORDER); + if (override == null || override.length == 0) { + resources.addAll(DEFAULT_BORDERTECH_LOAD_ORDER); + } else { + resources.addAll(Arrays.asList(override)); + } + // Check for append resources + String[] append = configDefaults.getStringArray(PARAM_KEY_RESOURCE_APPEND); + if (append != null && append.length > 0) { + resources.addAll(Arrays.asList(append)); + } + return Collections.unmodifiableList(resources); + } + } diff --git a/src/test/java/com/github/bordertech/config/ConfigTest.java b/src/test/java/com/github/bordertech/config/ConfigTest.java index af53b0b..e8cc16f 100644 --- a/src/test/java/com/github/bordertech/config/ConfigTest.java +++ b/src/test/java/com/github/bordertech/config/ConfigTest.java @@ -33,4 +33,25 @@ public void testCopyConfigurationWithProps() { String actual = config.getString("kung.fu"); Assert.assertEquals("Copy should maintain properties", expected, actual); } + + @Test + public void testResourceOrder() { + Configuration config = Config.getInstance(); + Assert.assertEquals("Correct property value in defaults", "IN-DEFAULTS", config.getString("test.in.defaults")); + Assert.assertEquals("Correct property value in app", "IN-APP", config.getString("test.in.app")); + Assert.assertEquals("Correct property value in local", "IN-LOCAL", config.getString("test.in.local")); + Assert.assertEquals("Correct property value in extra first", "IN-EXTRA-FIRST", config.getString("test.in.extra.first")); + Assert.assertEquals("Correct property value in extra second", "IN-EXTRA-SECOND", config.getString("test.in.extra.second")); + } + + @Test + public void testResourceOrderOverrides() { + Configuration config = Config.getInstance(); + Assert.assertEquals("Correct property override value in defaults", "DEFAULTS-def", config.getString("test.override.defaults")); + Assert.assertEquals("Correct property override value in app", "APP-app", config.getString("test.override.app")); + Assert.assertEquals("Correct property override value in local", "LOCAL-local", config.getString("test.override.local")); + Assert.assertEquals("Correct property override value in extra first", "EXTRA-FIRST-extra-1", config.getString("test.override.extra.first")); + Assert.assertEquals("Correct property override value in extra second", "EXTRA-SECOND-extra-2", config.getString("test.override.extra.second")); + } + } diff --git a/src/test/resources/bordertech-app.properties b/src/test/resources/bordertech-app.properties new file mode 100644 index 0000000..82a9606 --- /dev/null +++ b/src/test/resources/bordertech-app.properties @@ -0,0 +1,8 @@ +## Check properties are correctly overriden in resource order +test.override.app=APP-app +test.override.local=APP-local +test.override.extra.first=APP-extra-1 +test.override.extra.second=APP-extra-2 + +# Property only in app +test.in.app=IN-APP diff --git a/src/test/resources/bordertech-config.properties b/src/test/resources/bordertech-config.properties new file mode 100644 index 0000000..783319e --- /dev/null +++ b/src/test/resources/bordertech-config.properties @@ -0,0 +1,2 @@ +## Append the extra property to the default resources +bordertech.config.resource.append=bordertech-extra-first.properties,bordertech-extra-second.properties diff --git a/src/test/resources/bordertech-defaults.properties b/src/test/resources/bordertech-defaults.properties new file mode 100644 index 0000000..1c311b2 --- /dev/null +++ b/src/test/resources/bordertech-defaults.properties @@ -0,0 +1,9 @@ +## Check properties are correctly overriden in resource order +test.override.defaults=DEFAULTS-def +test.override.app=DEFAULTS-app +test.override.local=DEFAULTS-local +test.override.extra.first=DEFAULTS-extra-1 +test.override.extra.second=DEFAULTS-extra-2 + +# Property only in defaults +test.in.defaults=IN-DEFAULTS diff --git a/src/test/resources/bordertech-extra-first.properties b/src/test/resources/bordertech-extra-first.properties new file mode 100644 index 0000000..13775eb --- /dev/null +++ b/src/test/resources/bordertech-extra-first.properties @@ -0,0 +1,6 @@ +## Check properties are correctly overriden in resource order +test.override.extra.first=EXTRA-FIRST-extra-1 +test.override.extra.second=EXTRA-FIRST-extra-2 + +# Property only in extra +test.in.extra.first=IN-EXTRA-FIRST diff --git a/src/test/resources/bordertech-extra-second.properties b/src/test/resources/bordertech-extra-second.properties new file mode 100644 index 0000000..9536fb7 --- /dev/null +++ b/src/test/resources/bordertech-extra-second.properties @@ -0,0 +1,5 @@ +## Check properties are correctly overriden in resource order +test.override.extra.second=EXTRA-SECOND-extra-2 + +# Property only in extra second +test.in.extra.second=IN-EXTRA-SECOND diff --git a/src/test/resources/bordertech-local.properties b/src/test/resources/bordertech-local.properties new file mode 100644 index 0000000..fa99fab --- /dev/null +++ b/src/test/resources/bordertech-local.properties @@ -0,0 +1,7 @@ +## Check properties are correctly overriden in resource order +test.override.local=LOCAL-local +test.override.extra.first=LOCAL-extra-1 +test.override.extra.second=LOCAL-extra-2 + +# Property only in local +test.in.local=IN-LOCAL From 0fa2325c4c9b8b77f330c314b3e28a4dbb0a2c56 Mon Sep 17 00:00:00 2001 From: Jonathan Austin Date: Thu, 26 Mar 2020 17:32:13 +1100 Subject: [PATCH 04/11] Option to load environment properties --- .../config/DefaultConfiguration.java | 87 ++++++++++++++----- .../DefaultConfigurationSystemTest.java | 10 +-- ...aultConfigurationTestLoadSystem.properties | 2 +- ...ionTestLoadSystemOverWriteOnly.properties} | 14 ++- 4 files changed, 82 insertions(+), 31 deletions(-) rename src/test/resources/com/github/bordertech/config/{DefaultConfigurationTestLoadSystemOverWrite.properties => DefaultConfigurationTestLoadSystemOverWriteOnly.properties} (53%) diff --git a/src/main/java/com/github/bordertech/config/DefaultConfiguration.java b/src/main/java/com/github/bordertech/config/DefaultConfiguration.java index cb93a25..4159eaf 100644 --- a/src/main/java/com/github/bordertech/config/DefaultConfiguration.java +++ b/src/main/java/com/github/bordertech/config/DefaultConfiguration.java @@ -78,8 +78,11 @@ public class DefaultConfiguration implements Configuration { /** * If merging System Properties this parameter controls if a system property will only overwrite an existing - * property. The default is true. + * property. The default is false. + * + * @deprecated Use {@link #USE_SYSTEM_PREFIXES} to control which properties can be merged */ + @Deprecated public static final String USE_SYSTEM_OVERWRITEONLY = "bordertech.config.parameters.useSystemOverWriteOnly"; /** @@ -88,6 +91,18 @@ public class DefaultConfiguration implements Configuration { */ public static final String USE_SYSTEM_PREFIXES = "bordertech.config.parameters.useSystemPrefixes"; + /** + * If this parameter is defined and resolves to true as a boolean, then the OS Environment properties will be merged + * at the end of the loading process. + */ + public static final String USE_OSENV_PROPERTIES = "bordertech.config.parameters.useEnvProperties"; + + /** + * If merging OS Environment Properties, this parameter can be used to define a list of attribute prefixes that are + * allowed to be merged. The default is allow all Environment Properties to be merged. + */ + public static final String USE_OSENV_PREFIXES = "bordertech.config.parameters.useEnvPrefixes"; + /** * If this parameter is set to true, then after loading the parameters, they will be dumped to the console. */ @@ -295,6 +310,11 @@ private void load() { loadSystemProperties(); } + if (isUseOsEnvProperties()) { + recordMessage("Loading from environment properties"); + loadEnvironmentProperties(); + } + // Now perform variable substitution. do { // Do nothing while loop @@ -328,6 +348,13 @@ private boolean isUseSystemProperties() { return getBoolean(USE_SYSTEM_PROPERTIES) || getBoolean(LEGACY_USE_SYSTEM_PROPERTIES); } + /** + * @return true if load OS Environment properties into config + */ + private boolean isUseOsEnvProperties() { + return getBoolean(USE_OSENV_PROPERTIES); + } + /** * @return true if dump properties to the console */ @@ -705,33 +732,51 @@ private ClassLoader getParamsClassLoader() { * Load the System Properties into Config. */ private void loadSystemProperties() { - - boolean overWriteOnly = getBoolean(USE_SYSTEM_OVERWRITEONLY, true); + boolean overWriteOnly = getBoolean(USE_SYSTEM_OVERWRITEONLY, false); List allowedPrefixes = getList(USE_SYSTEM_PREFIXES); + System.getProperties().entrySet().forEach((entry) -> { + mergeExternalProperty("System Properties", (String) entry.getKey(), (String) entry.getValue(), overWriteOnly, allowedPrefixes); + }); + } - for (Map.Entry entry : System.getProperties().entrySet()) { - - String key = (String) entry.getKey(); - String value = (String) entry.getValue(); + /** + * Load the OS Environment Properties into Config. + */ + private void loadEnvironmentProperties() { + List allowedPrefixes = getList(USE_OSENV_PREFIXES); + System.getenv().entrySet().forEach((entry) -> { + mergeExternalProperty("Environment Properties", entry.getKey(), entry.getValue(), false, allowedPrefixes); + }); + } - // Check for "include" keys (should not come from System Properties) - if (INCLUDE.equals(key) || INCLUDE_AFTER.equals(key)) { - continue; - } + /** + * Merge the external property. + * + * @param location the location of the properties + * @param key the property key + * @param value the property value + * @param overWriteOnly true if only overwrite existing properties + * @param allowedPrefixes the list of allowed property prefixes + */ + private void mergeExternalProperty(final String location, final String key, final String value, final boolean overWriteOnly, final List allowedPrefixes) { - // Check allowed prefixes - if (!isAllowedKeyPrefix(allowedPrefixes, key)) { - continue; - } + // Check for "include" keys (should not come from System or Environment Properties) + if (INCLUDE.equals(key) || INCLUDE_AFTER.equals(key)) { + return; + } - // Check overwrite only - if (overWriteOnly && get(key) == null) { - continue; - } + // Check allowed prefixes + if (!isAllowedKeyPrefix(allowedPrefixes, key)) { + return; + } - // Load property - load(key, value, "System Properties"); + // Check overwrite only + if (overWriteOnly && get(key) == null) { + return; } + + // Load property + load(key, value, location); } /** diff --git a/src/test/java/com/github/bordertech/config/DefaultConfigurationSystemTest.java b/src/test/java/com/github/bordertech/config/DefaultConfigurationSystemTest.java index 7e14ce9..dba2b8f 100644 --- a/src/test/java/com/github/bordertech/config/DefaultConfigurationSystemTest.java +++ b/src/test/java/com/github/bordertech/config/DefaultConfigurationSystemTest.java @@ -45,11 +45,11 @@ public static void clearSystemProperties() { @Test public void loadSystemOverWriteOnly() { DefaultConfiguration config = new DefaultConfiguration( - "com/github/bordertech/config/DefaultConfigurationTestLoadSystem.properties"); + "com/github/bordertech/config/DefaultConfigurationTestLoadSystemOverWriteOnly.properties"); // Check system settings in the test properties files Assert.assertTrue(config.getBoolean(DefaultConfiguration.USE_SYSTEM_PROPERTIES)); // OverWriteOnly Enabled - ie using the default so no property set - Assert.assertFalse(config.containsKey(DefaultConfiguration.USE_SYSTEM_OVERWRITEONLY)); + Assert.assertTrue(config.containsKey(DefaultConfiguration.USE_SYSTEM_OVERWRITEONLY)); // No prefixes set Assert.assertFalse(config.containsKey(DefaultConfiguration.USE_SYSTEM_PREFIXES)); // Check properties @@ -58,12 +58,12 @@ public void loadSystemOverWriteOnly() { } @Test - public void loadSystemOverWriteOnlyDisabled() { + public void loadSystemProperties() { DefaultConfiguration config = new DefaultConfiguration( - "com/github/bordertech/config/DefaultConfigurationTestLoadSystemOverWrite.properties"); + "com/github/bordertech/config/DefaultConfigurationTestLoadSystem.properties"); // Check system settings in the test properties files Assert.assertTrue(config.getBoolean(DefaultConfiguration.USE_SYSTEM_PROPERTIES)); - // OverWriteOnly disabled + // OverWriteOnly disabled (default) Assert.assertFalse(config.getBoolean(DefaultConfiguration.USE_SYSTEM_OVERWRITEONLY)); // No prefixes set Assert.assertFalse(config.containsKey(DefaultConfiguration.USE_SYSTEM_PREFIXES)); diff --git a/src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadSystem.properties b/src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadSystem.properties index f9395f3..886b623 100644 --- a/src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadSystem.properties +++ b/src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadSystem.properties @@ -14,5 +14,5 @@ bordertech.config.parameters.useSystemProperties=true ## Following Properties will be set in System.Properties and merged ## Should be overwritten as it exists simple.exists=value1 -## Should not be overwritten as not set +## Should be merged even though not exist ##simple.notexists= diff --git a/src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadSystemOverWrite.properties b/src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadSystemOverWriteOnly.properties similarity index 53% rename from src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadSystemOverWrite.properties rename to src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadSystemOverWriteOnly.properties index 04440ff..f24a3ad 100644 --- a/src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadSystemOverWrite.properties +++ b/src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadSystemOverWriteOnly.properties @@ -8,8 +8,14 @@ ###### Test Load System Properteis with OverWriteOnly Disabled ###### -## Test Properties -include=com/github/bordertech/config/DefaultConfigurationTestLoadSystem.properties +## Load System Properties +bordertech.config.parameters.useSystemProperties=true -## Disable Overwrite Only -bordertech.config.parameters.useSystemOverWriteOnly=false +## Following Properties will be set in System.Properties and merged +## Should be overwritten as it exists +simple.exists=value1 +## Should not be overwritten as not set +##simple.notexists= + +## Enable Overwrite Only +bordertech.config.parameters.useSystemOverWriteOnly=true From 4108ccad23678e970f73e6a3fbbc0afc9d6554a9 Mon Sep 17 00:00:00 2001 From: Jonathan Austin Date: Thu, 26 Mar 2020 17:47:02 +1100 Subject: [PATCH 05/11] Update README.md --- README.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1c31cbb..db14307 100644 --- a/README.md +++ b/README.md @@ -121,8 +121,21 @@ Sometimes you may need to include System Properties in the Configuration: |Property key|Description|Default value| |-------------|-----------|-------------| |bordertech.config.parameters.useSystemProperties|This flag allows system properties to be merged into the Configuration at the end of the loading process.|false| -|bordertech.config.parameters.useSystemOverWriteOnly|This flag controls if a system property will only overwrite an existing property|true| -|bordertech.config.parameters.useSystemPrefixes|Define a list of system attribute prefixes that are allowed to be merged. Default is allow all.|n/a| +|bordertech.config.parameters.useSystemOverWriteOnly|This flag controls if a system property will only overwrite an existing property|false| +|bordertech.config.parameters.useSystemPrefixes|Define a list of system property prefixes that are allowed to be merged. Default is allow all.|n/a| + +System properties will override properties in resource files. + +### Merge Environment Properties into Configuration + +Sometimes you may need to include Environment Properties in the Configuration: + +|Property key|Description|Default value| +|-------------|-----------|-------------| +|bordertech.config.parameters.useEnvProperties|This flag allows environment properties to be merged into the Configuration at the end of the loading process.|false| +|bordertech.config.parameters.useEnvPrefixes|Define a list of environment property prefixes that are allowed to be merged. Default is allow all.|n/a| + +Environemnt properties will override system properties and properties in resource files. ### Merge Configuration into System Properties @@ -161,7 +174,7 @@ The following methods in the `Config` class are useful for unit testing: ## Configuration -The initial configuration of `Config` can be overridden by setting properties in a file `bordertech-config.properties`. +The initial configuration of `Config` can be overridden by setting properties in a file `bordertech-config.properties`. The file name can be overriden via a System or Environment property `BT_CONFIG_FILE`. The following options can be set:- @@ -171,6 +184,7 @@ The following options can be set:- |bordertech.config.spi.enabled|The flag to enable SPI lookup|true| |bordertech.config.spi.append.default|The flag to append the default configuration|true| |bordertech.config.resource.order|The list of property resources to load into the configuration. Priority of properties is in reverse order of the list.|bordertech-defaults.properties, bordertech-app.properties, bordertech-local.properties| +|bordertech.config.resource.append|An optional list of extra property resources to append to the resources. Useful to add extra resources to the default resources.|n/a| ### Default Implementation @@ -185,7 +199,7 @@ bordertech.config.default.impl=my.example.SpecialConfiguration Example of loading the default resources and a project specific resource: ``` java properties -bordertech.config.resource.order+=my-project.properties +bordertech.config.resource.append=my-project.properties ``` ### SPI From cdc33332e5f814202f9e87addcc39774f69043b8 Mon Sep 17 00:00:00 2001 From: Jonathan Austin Date: Thu, 26 Mar 2020 17:49:11 +1100 Subject: [PATCH 06/11] Update config file name parameter key --- src/main/java/com/github/bordertech/config/InitHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/bordertech/config/InitHelper.java b/src/main/java/com/github/bordertech/config/InitHelper.java index 2b8f803..32f05a8 100644 --- a/src/main/java/com/github/bordertech/config/InitHelper.java +++ b/src/main/java/com/github/bordertech/config/InitHelper.java @@ -49,7 +49,7 @@ */ public final class InitHelper { - private static final String DEFAULTS_FILE_PARAM_KEY = "bordertech.config.file"; + private static final String DEFAULTS_FILE_PARAM_KEY = "BT_CONFIG_FILE"; private static final String DEFAULTS_FILE_NAME = "bordertech-config.properties"; private static final String PARAM_KEY_DEFAULT_CONFIG_IMPL = "bordertech.config.default.impl"; private static final String PARAM_KEY_SPI_ENABLED = "bordertech.config.spi.enabled"; From f16c299c173764b3679b9af5cfd35353f885b66c Mon Sep 17 00:00:00 2001 From: Jonathan Austin Date: Thu, 26 Mar 2020 17:50:09 +1100 Subject: [PATCH 07/11] Fix travis sonar token --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6e94012..f4d729a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,8 +7,7 @@ cache: addons: sonarcloud: organization: "bordertech-github" - token: - secure: $SONAR_TOKEN + token: $SONAR_TOKEN before_install: - echo "MAVEN_OPTS='-Xmx512m -XX:MaxPermSize=128m'" > ~/.mavenrc From 325dc8491c067b65516d76a88633f840f11ae3f3 Mon Sep 17 00:00:00 2001 From: Jonathan Austin Date: Thu, 26 Mar 2020 18:00:18 +1100 Subject: [PATCH 08/11] Update javadoc --- .../bordertech/config/DefaultConfiguration.java | 12 ++++++------ .../com/github/bordertech/config/InitHelper.java | 7 +++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/github/bordertech/config/DefaultConfiguration.java b/src/main/java/com/github/bordertech/config/DefaultConfiguration.java index 4159eaf..22d0c2b 100644 --- a/src/main/java/com/github/bordertech/config/DefaultConfiguration.java +++ b/src/main/java/com/github/bordertech/config/DefaultConfiguration.java @@ -734,9 +734,9 @@ private ClassLoader getParamsClassLoader() { private void loadSystemProperties() { boolean overWriteOnly = getBoolean(USE_SYSTEM_OVERWRITEONLY, false); List allowedPrefixes = getList(USE_SYSTEM_PREFIXES); - System.getProperties().entrySet().forEach((entry) -> { - mergeExternalProperty("System Properties", (String) entry.getKey(), (String) entry.getValue(), overWriteOnly, allowedPrefixes); - }); + System.getProperties().entrySet().forEach(entry + -> mergeExternalProperty("System Properties", (String) entry.getKey(), (String) entry.getValue(), overWriteOnly, allowedPrefixes) + ); } /** @@ -744,9 +744,9 @@ private void loadSystemProperties() { */ private void loadEnvironmentProperties() { List allowedPrefixes = getList(USE_OSENV_PREFIXES); - System.getenv().entrySet().forEach((entry) -> { - mergeExternalProperty("Environment Properties", entry.getKey(), entry.getValue(), false, allowedPrefixes); - }); + System.getenv().entrySet().forEach(entry + -> mergeExternalProperty("Environment Properties", entry.getKey(), entry.getValue(), false, allowedPrefixes) + ); } /** diff --git a/src/main/java/com/github/bordertech/config/InitHelper.java b/src/main/java/com/github/bordertech/config/InitHelper.java index 32f05a8..7ffe1a3 100644 --- a/src/main/java/com/github/bordertech/config/InitHelper.java +++ b/src/main/java/com/github/bordertech/config/InitHelper.java @@ -13,10 +13,9 @@ /** * Helper class for {@link Config} initialisation. *

    - * The helper checks for configuration overrides by searching for a property file named - * bordertech-config.properties in the user home directory, the current classpath and the system classpath. - * The file name can be overridden by setting an environment or system property with the key - * bordertech.config.file. + * The helper checks for configuration overrides by searching for a property file named BT_CONFIG_FILE in + * the user home directory, the current classpath and the system classpath. The file name can be overridden by setting + * an environment or system property with the key bordertech.config.file. *

    *

    * The following properties can be set:- From 31807152718734650412cba48a64ae285c3157a3 Mon Sep 17 00:00:00 2001 From: Jonathan Austin Date: Fri, 27 Mar 2020 00:44:48 +1100 Subject: [PATCH 09/11] Add change log. --- CHANGELOG.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 4 ++-- 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..1262b80 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,51 @@ +# Change log + +## Release in-progress + +### API Changes +* The runtime property `bordertech.config.parameters.useSystemOverWriteOnly` now defaults to false which allows all system properties to be + merged when system properties enabled. Use the optional runtime property `bordertech.config.parameters.useSystemPrefixes` to limit the + properties merged. + +### Enhancements +* Latest qa-parent +* Ability to override the default config file name via a system or environment property `BT_CONFIG_FILE=my-config.properties` +* Option to append extra resources to the defined resources via config property `bordertech.config.resources.append` +* Option to load environment variables #13 + * Enable via runtime property `bordertech.config.parameters.useEnvProperties=true` + * Option to limit variables merged via property `bordertech.config.parameters.useEnvPrefixes`. Defaults to allow all. + +## 1.0.5 + +### Enhancements +* Latest qa-parent #27 +* Improve README #24 + +## 1.0.4 + +### Enhancements +* Optional dump parameters to a file. The file name can be set via runtime property `bordertech.config.parameters.dump.file` +* Optional merge system properties into config. + * Enable system properties via runtime property `bordertech.config.parameters.useSystemProperties=true` + * Option to limit system properties merged via runtime property `bordertech.config.parameters.useSystemPrefixes`. Defaults to allow all. + * Defaults to only merge properties that already exist. Disable via runtime property `bordertech.config.parameters.useSystemOverWriteOnly=false` + +## 1.0.3 + +### Enhancements +* Latest qa-parent + +## 1.0.2 +* Latest qa-parent +* Switch to travis +* The reload of the configuration can be triggered via a touchfile. The touchfile can be set via the runtime property`bordertech.config.touchfile`. + To avoid excessive IO on the touchfile an interval (in milli seconds) between checks can be set via the runtime property + `bordertech.config.touchfile.interval` which defaults to 10000ms. + +## 1.0.1 +* Ability to define properties to only take effect in a certain environment. When the runtime property `bordertech.config.environment` is set, + it is used as the suffix for each property lookup. If no property exists with the current environment suffix then the default property (ie no + suffix) value is used. + +## 1.0.0 +* Initial version diff --git a/README.md b/README.md index db14307..f7c2d31 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=bordertech-java-config&metric=alert_status)](https://sonarcloud.io/dashboard?id=bordertech-java-config) [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=bordertech-java-config&metric=reliability_rating)](https://sonarcloud.io/dashboard?id=bordertech-java-config) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=bordertech-java-config&metric=coverage)](https://sonarcloud.io/dashboard?id=bordertech-java-config) -[![Codacy Badge](https://api.codacy.com/project/badge/Grade/738a3851c483470da86ffe1d047f344c)](https://www.codacy.com/app/BorderTech/java-config?utm_source=github.com&utm_medium=referral&utm_content=BorderTech/java-config&utm_campaign=Badge_Grade) +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/ff9d14e9be2c4071b5e94bed4c7545cb)](https://www.codacy.com/gh/BorderTech/java-config?utm_source=github.com&utm_medium=referral&utm_content=BorderTech/java-config&utm_campaign=Badge_Grade) [![Javadocs](https://www.javadoc.io/badge/com.github.bordertech.config/config.svg)](https://www.javadoc.io/doc/com.github.bordertech.config/config) [![Maven Central](https://img.shields.io/maven-central/v/com.github.bordertech.config/config.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22com.github.bordertech.config%22%20AND%20a:%22config%22) @@ -87,7 +87,7 @@ include=another.properties It is possible to define properties to only take effect in a certain environment. -When the environment property is set, it is used as the suffix for each property lookup: +When the runtime property `bordertech.config.environment` is set, it is used as the suffix for each property lookup: ``` java properties ## MOCK Environment From fdeb5d29158e069af4fb16f6c5a33920704da938 Mon Sep 17 00:00:00 2001 From: Jonathan Austin Date: Fri, 27 Mar 2020 00:49:49 +1100 Subject: [PATCH 10/11] Update change log --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1262b80..36cc91e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ * Latest qa-parent * Ability to override the default config file name via a system or environment property `BT_CONFIG_FILE=my-config.properties` * Option to append extra resources to the defined resources via config property `bordertech.config.resources.append` -* Option to load environment variables #13 +* Option to load environment variables #31 * Enable via runtime property `bordertech.config.parameters.useEnvProperties=true` * Option to limit variables merged via property `bordertech.config.parameters.useEnvPrefixes`. Defaults to allow all. From f4fcc3537fba54b7e0a9c8b4b54bd184878011df Mon Sep 17 00:00:00 2001 From: Jonathan Austin Date: Fri, 27 Mar 2020 02:11:16 +1100 Subject: [PATCH 11/11] Extra unit tests --- .../DefaultConfigurationEnvironmentTest.java | 39 +++++++++++++ .../bordertech/config/InitHelperTest.java | 56 +++++++++++++++++++ .../InvalidPropertiesFile.properties | 2 + ...ConfigurationTestLoadEnvDefault.properties | 12 ++++ ...ConfigurationTestLoadEnvEnabled.properties | 12 ++++ 5 files changed, 121 insertions(+) create mode 100644 src/test/java/com/github/bordertech/config/DefaultConfigurationEnvironmentTest.java create mode 100644 src/test/java/com/github/bordertech/config/InitHelperTest.java create mode 100644 src/test/resources/InvalidPropertiesFile.properties create mode 100644 src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadEnvDefault.properties create mode 100644 src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadEnvEnabled.properties diff --git a/src/test/java/com/github/bordertech/config/DefaultConfigurationEnvironmentTest.java b/src/test/java/com/github/bordertech/config/DefaultConfigurationEnvironmentTest.java new file mode 100644 index 0000000..6426a55 --- /dev/null +++ b/src/test/java/com/github/bordertech/config/DefaultConfigurationEnvironmentTest.java @@ -0,0 +1,39 @@ +package com.github.bordertech.config; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Unit test {@link DefaultConfiguration} for environment variables. + */ +public class DefaultConfigurationEnvironmentTest { + + @Test + public void testEnvironmentVariablesDefault() { + DefaultConfiguration config = new DefaultConfiguration( + "com/github/bordertech/config/DefaultConfigurationTestLoadEnvDefault.properties"); + // Check disabled + Assert.assertFalse("Use environment variables should defualt to false", config.getBoolean(DefaultConfiguration.USE_OSENV_PROPERTIES)); + // If no environment variables cant do anything + if (!System.getenv().keySet().isEmpty()) { + // Get a environment variable + String key = System.getenv().keySet().iterator().next(); + Assert.assertFalse("Environment variables should not be in config", config.containsKey(key)); + } + } + + @Test + public void testEnvironmentVariablesEnabled() { + DefaultConfiguration config = new DefaultConfiguration( + "com/github/bordertech/config/DefaultConfigurationTestLoadEnvEnabled.properties"); + // Check enabled + Assert.assertTrue("Use environment variables should be enabled", config.getBoolean(DefaultConfiguration.USE_OSENV_PROPERTIES)); + // If no environment variables cant do anything + if (!System.getenv().keySet().isEmpty()) { + // Get a environment variable + String key = System.getenv().keySet().iterator().next(); + Assert.assertTrue("Environment variables should be in config", config.containsKey(key)); + } + } + +} diff --git a/src/test/java/com/github/bordertech/config/InitHelperTest.java b/src/test/java/com/github/bordertech/config/InitHelperTest.java new file mode 100644 index 0000000..4b14e59 --- /dev/null +++ b/src/test/java/com/github/bordertech/config/InitHelperTest.java @@ -0,0 +1,56 @@ +package com.github.bordertech.config; + +import java.util.Arrays; +import org.apache.commons.configuration.Configuration; +import org.junit.Assert; +import org.junit.Test; + +/** + * Unit tests for {@link InitHelper}. + */ +public class InitHelperTest { + + private final String[] expectedResources = new String[]{ + "bordertech-defaults.properties", + "bordertech-app.properties", + "bordertech-local.properties", + "bordertech-extra-first.properties", + "bordertech-extra-second.properties"}; + + private final String[] expectedBordertechResources = new String[]{ + "bordertech-defaults.properties", + "bordertech-app.properties", + "bordertech-local.properties"}; + + @Test + public void testResourceLoadOrder() { + String[] resources = InitHelper.getDefaultResourceLoadOrder(); + Assert.assertTrue("Incorrect resource load order", Arrays.deepEquals(expectedResources, resources)); + } + + @Test + public void testBordertechDefaultLoadOrder() { + String[] resources = InitHelper.getDefaultBordertechLoadOrder(); + Assert.assertTrue("Incorrect bordertech resources", Arrays.deepEquals(expectedBordertechResources, resources)); + } + + @Test + public void loadPropertyFileExists() { + Configuration config = InitHelper.loadPropertyFile("bordertech-app.properties"); + Assert.assertNotNull("Config for file should not be null", config); + Assert.assertEquals("Incorrect property value returned from config", "IN-APP", config.getString("test.in.app")); + } + + @Test + public void loadPropertyFileNotExists() { + Configuration config = InitHelper.loadPropertyFile("NOT-EXIST.properties"); + Assert.assertNotNull("Config for not existing file should not be null", config); + Assert.assertFalse("Config should be empty", config.getKeys().hasNext()); + } + + @Test(expected = IllegalStateException.class) + public void loadPropertyFileInvalid() { + InitHelper.loadPropertyFile("InvalidPropertiesFile.properties"); + } + +} diff --git a/src/test/resources/InvalidPropertiesFile.properties b/src/test/resources/InvalidPropertiesFile.properties new file mode 100644 index 0000000..6efc65d --- /dev/null +++ b/src/test/resources/InvalidPropertiesFile.properties @@ -0,0 +1,2 @@ +## This include will cause an error when testing InitHelper +include=NotExists.properties diff --git a/src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadEnvDefault.properties b/src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadEnvDefault.properties new file mode 100644 index 0000000..837d9f8 --- /dev/null +++ b/src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadEnvDefault.properties @@ -0,0 +1,12 @@ +############################################################################ +# This property file is for the DefaultConfiguration_Test jUnit test +# It must not be included or be included by property file that is not +# directly related to the test. +############################################################################ + +###### +###### Test load Environment Properties +###### + +## Load Environment Properties should default to false +##bordertech.config.parameters.useEnvProperties=false diff --git a/src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadEnvEnabled.properties b/src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadEnvEnabled.properties new file mode 100644 index 0000000..ff3fa5f --- /dev/null +++ b/src/test/resources/com/github/bordertech/config/DefaultConfigurationTestLoadEnvEnabled.properties @@ -0,0 +1,12 @@ +############################################################################ +# This property file is for the DefaultConfiguration_Test jUnit test +# It must not be included or be included by property file that is not +# directly related to the test. +############################################################################ + +###### +###### Test load Environment Properties +###### + +## Load Environment Properties Enabled +bordertech.config.parameters.useEnvProperties=true