Skip to content

Commit

Permalink
Updates for working with environment variables when running with Gauge (
Browse files Browse the repository at this point in the history
  • Loading branch information
haroon-sheikh committed Feb 3, 2023
1 parent a59e57c commit 3b222aa
Show file tree
Hide file tree
Showing 17 changed files with 437 additions and 346 deletions.
21 changes: 15 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ All notable changes to this project are documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## 1.4.0

### Updated

- Adds additional test coverage for config precedence
- Updates for following Gauge specific scenarios:
- when env var value and default config file value is same and does not contain in env config file then it should ignore the env var
- when env var value and env config file value is same and does not exist in default then value from env var takes priority

## 1.3.0

### Updated
Expand All @@ -20,7 +29,7 @@ and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

### Fixed

- System environment should now take precedence over keepass
- System environment should now take precedence over keepass

## 1.2.2

Expand Down Expand Up @@ -118,7 +127,7 @@ and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

### Updated

- Updating to latest version of checkstyle and pmd
- Updating to the latest version of checkstyle and pmd

## 0.8.1

Expand Down Expand Up @@ -182,14 +191,14 @@ and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

### Updated

- Migrating to use github actions
- Publishing to both maven central and github packages
- Migrating to use GitHub actions
- Publishing to both maven central and GitHub packages

## 0.5.6

### Updated

- Updates to latest version of checkstyle/pmd.
- Updates to the latest version of checkstyle/pmd.
- Updates the version of compiler plugin

## 0.5.5
Expand All @@ -208,7 +217,7 @@ and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

### Changed

- Now adds the raw environments as well as processed lowercased keys
- Now adds the raw environments as well as processed lowercase keys

E.g. TEST_VAR can either be retrieved with `EnvConfig.get("TEST_VAR")` or `EnvConfig.get("test.var")`

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ compile 'com.github.sitture:env-config:${version}'
| `env.config.profile` | `ENV_CONFIG_PROFILE` | The profile to activate from the active environment directory. |
| `env.config.keepass.enabled` | `ENV_CONFIG_KEEPASS_ENABLED` | Whether to load properties from a keepass file. **default:** `false` |
| `env.config.keepass.filename` | `ENV_CONFIG_KEEPASS_FILENAME` | The keepass filename to load from the resources folder (src/main/resources). **default:** the root project directory name. i.e. `project.build.directory` |
| `env.config.keepass.masterkey` | `ENV_CONFIG_KEEPASS_MASTERKEY` | The password to open the keepass file. This is required if `env.config.keepass.enabled=true`. |
| `env.config.keepass.masterkey` | `ENV_CONFIG_KEEPASS_MASTERKEY` | The password to open the keepass file. This is required if `env.config.keepass.enabled=true`. |

## Configuration precedence

Expand Down
3 changes: 2 additions & 1 deletion config/default/default.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ property.four=default
property.five=default
property.six=default
prof1.one=default
PROPERTY_SEVEN=default
PROPERTY_SEVEN=default
property.eight=default
3 changes: 1 addition & 2 deletions config/test/test.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
my.property=my_value
my.keepass.property=my_value
property.keepass=test
property.one=test
property.three=test
property.five=test
Expand Down
8 changes: 7 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<groupId>com.github.sitture</groupId>
<artifactId>env-config</artifactId>
<packaging>jar</packaging>
<version>1.3.0</version>
<version>1.4.0</version>

<name>env-config</name>
<description>A simple utility to manage environment configs in Java-based projects by merging *.properties files with environment variables overrides.</description>
Expand Down Expand Up @@ -171,6 +171,12 @@
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-reload4j</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/com/github/sitture/envconfig/EnvConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ private static Optional<String> getProperty(final String property) {
*/
public static String getOrThrow(final String property) {
return getProperty(property)
.orElseThrow(() -> new EnvConfigException("Missing required variable '" + property + "'"));
.orElseThrow(() -> new EnvConfigException("Missing required key '" + property + "'"));
}

/**
Expand Down Expand Up @@ -124,8 +124,7 @@ public static int getInt(final String property) {
* Returns a key/value from a named config, parsed as Boolean.
*
* @param property the property
* @return a Boolean representing the value, false if the value not present or
* cannot be parsed as Boolean
* @return a Boolean representing the value, false if the value not present
*/
public static boolean getBool(final String property) {
return getProperty(property).map(Boolean::parseBoolean).orElse(false);
Expand Down Expand Up @@ -160,7 +159,7 @@ public static List<String> getList(final String property, final String delimiter
* @return env property value.
*/
public static String getEnvironment() {
return getConfig().configProperties.getEnvironments().get(0);
return getConfig().configProperties.getCurrentEnvironment();
}

public static Map<String, Object> asMap() {
Expand Down
73 changes: 49 additions & 24 deletions src/main/java/com/github/sitture/envconfig/EnvConfigLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,58 +16,83 @@
class EnvConfigLoader {

private static final Logger LOG = LoggerFactory.getLogger(EnvConfigLoader.class);
public static final int ENVIRONMENTS_WITH_PARENT = 2;
protected final CompositeConfiguration configuration = new CompositeConfiguration();
protected final EnvConfigProperties configProperties = new EnvConfigProperties();

EnvConfigLoader() {
final List<String> environments = this.configProperties.getEnvironments();
final String configProfile = this.configProperties.getConfigProfile();
loadEnvConfigurations(environments);
final Map<String, Configuration> envConfiguration = getEnvironmentConfiguration(environments);
loadEnvConfigurations(envConfiguration);
loadKeepassConfigurations(environments);
if (!configProfile.isEmpty()) {
LOG.debug("Loading properties from profile {} under environments {}", configProfile, environments);
environments.forEach(env -> loadFileConfigurations(new EnvConfigProfileFileList(this.configProperties.getConfigProfilePath(env, configProfile))));
final Map<String, Configuration> profileConfiguration = getEnvironmentProfileConfiguration(environments, configProfile);
LOG.debug("Loading config from profile {} under environments {}", configProfile, environments);
environments.forEach(env -> this.configuration.addConfiguration(profileConfiguration.get(env)));
}
LOG.debug("Loading properties from environment directories {}", environments);
environments.forEach(env -> loadFileConfigurations(new EnvConfigFileList(this.configProperties.getConfigPath(env))));
LOG.debug("Loading config from environment directories {}", environments);
environments.forEach(env -> this.configuration.addConfiguration(envConfiguration.get(env)));
}

private void loadKeepassConfigurations(final List<String> environments) {
if (this.configProperties.isConfigKeePassEnabled()) {
final String groupName = this.configProperties.getConfigKeePassFilename();
final String masterKey = this.configProperties.getConfigKeePassMasterKey();
LOG.debug("Loading properties from keepass {}", groupName);
LOG.debug("Loading config from keepass {}", groupName);
final KeePassEntries keepassEntries = new KeePassEntries(masterKey, groupName);
environments.forEach(env -> this.configuration.addConfiguration(keepassEntries.getEntriesConfiguration(env)));
}
}

private void loadEnvConfigurations(final List<String> environments) {
final EnvironmentVariables envVars = new EnvironmentVariables();
LOG.debug("Loading properties from system.properties");
this.configuration.addConfiguration(envVars.getSystemConfiguration());
final Configuration envOverrides = envVars.getEnvironmentConfiguration();
environments.forEach(env -> {
for (final File file : new EnvConfigFileList(this.configProperties.getConfigPath(env)).listFiles()) {
final Map<String, Object> configurationMap = getFileConfigurationMap(file);
configurationMap.keySet().forEach(key -> {
if (envOverrides.containsKey(key)
&& configurationMap.get(key).equals(envOverrides.getProperty(key))) {
envOverrides.clearProperty(key);
}
});
private void loadEnvConfigurations(final Map<String, Configuration> configurationMap) {
final EnvironmentVariables variables = new EnvironmentVariables();
LOG.debug("Loading config from system.properties");
this.configuration.addConfiguration(variables.getSystemConfiguration());
final Configuration envOverrides = variables.getEnvironmentConfiguration();
final Configuration currentEnvironment = configurationMap.get(this.configProperties.getCurrentEnvironment());
currentEnvironment.getKeys().forEachRemaining(key -> {
if (envOverrides.containsKey(key)
&& envOverrides.getProperty(key).equals(currentEnvironment.getString(key))) {
envOverrides.clearProperty(key);
}
});
LOG.debug("Loading properties from system.env");
if (!EnvConfigUtils.CONFIG_ENV_DEFAULT.equals(this.configProperties.getCurrentEnvironment())) {
final Configuration defaultEnvironment = configurationMap.get(EnvConfigUtils.CONFIG_ENV_DEFAULT);
defaultEnvironment.getKeys().forEachRemaining(key -> {
if (envOverrides.containsKey(key)
&& envOverrides.getProperty(key).equals(defaultEnvironment.getString(key))
&& (!currentEnvironment.containsKey(key) || configurationMap.size() > ENVIRONMENTS_WITH_PARENT)) {
envOverrides.clearProperty(key);
}
});
}
LOG.debug("Loading config from system.env");
this.configuration.addConfiguration(envOverrides);
}

private void loadFileConfigurations(final EnvConfigFileList fileList) {
private Map<String, Configuration> getEnvironmentProfileConfiguration(final List<String> environments, final String configProfile) {
final Map<String, Configuration> configurationMap = new HashMap<>();
environments.forEach(env -> configurationMap.put(
env, getConfiguration(new EnvConfigProfileFileList(this.configProperties.getConfigProfilePath(env, configProfile)))));
return configurationMap;
}

private Map<String, Configuration> getEnvironmentConfiguration(final List<String> environments) {
final Map<String, Configuration> configurationMap = new HashMap<>();
environments.forEach(env -> configurationMap.put(
env, getConfiguration(new EnvConfigFileList(this.configProperties.getConfigPath(env)))));
return configurationMap;
}

private Configuration getConfiguration(final EnvConfigFileList fileList) {
if (fileList.listFiles().isEmpty()) {
LOG.debug("No property files found under {}", fileList.configPath);
}
final CompositeConfiguration configuration = new CompositeConfiguration();
fileList.listFiles().forEach(file ->
this.configuration.addConfiguration(new MapConfiguration(getFileConfigurationMap(file))));
configuration.addConfiguration(new MapConfiguration(getFileConfigurationMap(file))));
return configuration;
}

private Map<String, Object> getFileConfigurationMap(final File file) {
Expand All @@ -84,7 +109,7 @@ private Map<String, Object> getFileConfigurationMap(final File file) {
private Configuration getConfigurationProperties(final File file) {
final Configuration configurationProperties;
try {
LOG.debug("Loading properties from {}", file);
LOG.debug("Getting config from {}", file);
configurationProperties = new Configurations().properties(file);
} catch (ConfigurationException e) {
throw new EnvConfigException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,18 @@ List<String> getEnvironments() {
return environments;
}

String getCurrentEnvironment() {
return environments.get(0);
}

String getConfigProfile() {
return getConfigurationProperty(EnvConfigUtils.CONFIG_PROFILE_KEY, "");
}

private List<String> getEnvList() {
final List<String> environments = new ArrayList<>();
environments.add(EnvConfigUtils.CONFIG_ENV_DEFAULT);
environments.addAll(EnvConfigUtils.getListOfValues(getConfigurationProperty(EnvConfigUtils.CONFIG_ENV_KEY, EnvConfigUtils.CONFIG_ENV_DEFAULT), EnvConfigUtils.CONFIG_DELIMITER_DEFAULT));
environments.addAll(EnvConfigUtils.getListOfValues(getConfigurationProperty(EnvConfigUtils.CONFIG_ENV_KEY, EnvConfigUtils.CONFIG_ENV_DEFAULT).toLowerCase(), EnvConfigUtils.CONFIG_DELIMITER_DEFAULT));
Collections.reverse(environments);
return environments.stream().distinct().collect(Collectors.toList());
}
Expand Down
18 changes: 9 additions & 9 deletions src/main/resources/config/checkstyle-suppressions.xml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">

<suppressions>
<!-- Suppress various checks in the test packages (directory /test/) -->
<suppress checks="JavadocPackage" files="[\\/]test[\\/]"/>
<suppress checks="JavadocVariable" files="[\\/]test[\\/]"/>
<suppress checks="JavadocMethod" files="[\\/]test[\\/]"/>
<suppress checks="MultipleStringLiterals" files="[\\/]test[\\/]"/>
<!-- Suppress all checks on generated sources -->
<suppress checks=".*" files="[\\/]generated[\\/]" />
<!-- Suppress various checks in the test packages (directory /test/) -->
<suppress checks="JavadocPackage" files="[\\/]test[\\/]"/>
<suppress checks="JavadocVariable" files="[\\/]test[\\/]"/>
<suppress checks="JavadocMethod" files="[\\/]test[\\/]"/>
<suppress checks="MultipleStringLiterals" files="[\\/]test[\\/]"/>
<!-- Suppress all checks on generated sources -->
<suppress checks=".*" files="[\\/]generated[\\/]"/>
</suppressions>
Loading

0 comments on commit 3b222aa

Please sign in to comment.