Skip to content

Commit

Permalink
Change the environment variable naming for namespaces. wso2#66
Browse files Browse the repository at this point in the history
  • Loading branch information
tharindu1st committed Oct 24, 2018
1 parent 882687a commit 6d34c4d
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
public class ConfigProviderImpl implements ConfigProvider {
private static final Logger logger = LoggerFactory.getLogger(ConfigProviderImpl.class.getName());
private static final String CONFIG_LEVEL_SEPARATOR = "_";
private static final String CONFIG_NAMESPACE_WORD_SEPERATOR = ".";

private static final int CONFIG_MIN_ELEMENT_COUNT = 2;
private static final String[] UNIQUE_ATTRIBUTE_NAMES = {"ID", "NAME"};
private static final String UNIQUE_ATTRIBUTE_SPECIFIER = "UNIQUE";
Expand Down Expand Up @@ -186,16 +188,24 @@ private Map<String, String> filterVariables(String namespace, Map<String, String
// Filter 2: Check if the key format is correct
// Filter 3: Check if the configuration is not empty
// Filter 4: Ignore unique identification specifiers
return variables.entrySet().stream()
.filter(entry -> entry.getKey().toUpperCase()
.startsWith(namespace.toUpperCase() + CONFIG_LEVEL_SEPARATOR))
.filter(entry -> (entry.getKey().split(CONFIG_LEVEL_SEPARATOR, CONFIG_MIN_ELEMENT_COUNT)
.length == CONFIG_MIN_ELEMENT_COUNT))
.filter(entry -> (!entry.getKey().split(CONFIG_LEVEL_SEPARATOR, CONFIG_MIN_ELEMENT_COUNT)[1]
.trim().isEmpty()))
.filter(entry -> (!entry.getKey().split(CONFIG_LEVEL_SEPARATOR, CONFIG_MIN_ELEMENT_COUNT)[1]
.toUpperCase().endsWith(UNIQUE_ATTRIBUTE_SPECIFIER.toUpperCase())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a, HashMap::new));
HashMap<String, String> map = new HashMap<>();
variables.entrySet().forEach((Map.Entry<String, String> entry) -> {
String environmentVariableNameSpacePart = namespace.toUpperCase().replace
(CONFIG_NAMESPACE_WORD_SEPERATOR, CONFIG_LEVEL_SEPARATOR) + CONFIG_LEVEL_SEPARATOR;
if (entry.getKey().toUpperCase().startsWith(environmentVariableNameSpacePart)) {
String[] splicedEnvironmentVariableParts = entry.getKey().split(environmentVariableNameSpacePart,
CONFIG_MIN_ELEMENT_COUNT);
if (splicedEnvironmentVariableParts.length == CONFIG_MIN_ELEMENT_COUNT) {
if ((!splicedEnvironmentVariableParts[1].trim().isEmpty())) {
if ((!splicedEnvironmentVariableParts[1].toUpperCase().endsWith(UNIQUE_ATTRIBUTE_SPECIFIER
.toUpperCase()))) {
map.putIfAbsent(entry.getKey(), entry.getValue());
}
}
}
}
});
return map;
}

/**
Expand Down Expand Up @@ -239,7 +249,9 @@ private <T> T overrideConfigWithSystemVars(String namespace, T configClass) thro

for (Map.Entry<String, String> entry : systemVariables.entrySet()) {
String systemVarKey = entry.getKey();
String configKey = systemVarKey.split(CONFIG_LEVEL_SEPARATOR, CONFIG_MIN_ELEMENT_COUNT)[1];
String environmentVariableNameSpacePart = namespace.toUpperCase(Locale.ENGLISH).replace
(CONFIG_NAMESPACE_WORD_SEPERATOR, CONFIG_LEVEL_SEPARATOR) + CONFIG_LEVEL_SEPARATOR;
String configKey = systemVarKey.split(environmentVariableNameSpacePart)[1];
String value = entry.getValue();

List<String> configKeyElements = new ArrayList<>(Arrays.asList(configKey.split(CONFIG_LEVEL_SEPARATOR)));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.config.configprovider;

import org.wso2.carbon.config.annotation.Configuration;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
* Sample configuration class for testing purposes.
*
* @since 1.0.0
*/
@XmlRootElement(name = "testconfiguration")
@Configuration(namespace = "wso2.test.config", description = "Test Configurations Bean")
public class ComplexNameSpaceConfiguration {

private String tenant = "default";
private Transports transports = new Transports();

@XmlElement
public void setTenant(String tenant) {
this.tenant = tenant;
}

public String getTenant() {
return tenant;
}

@XmlElement
public void setTransports(Transports transports) {
this.transports = transports;
}

public Transports getTransports() {
return transports;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ public void yamlConfigWithoutEnvValueTestCase() throws ConfigurationException {
"variables")
public void yamlConfigOverrideWithEnvVariable() throws ConfigurationException {
String newTenantName = "NewTenant";
String envVariable = CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR + "TENANT";
String envVariable = CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR + "TENANT";
EnvironmentUtils.setEnvironmentVariables(envVariable, newTenantName);
ConfigFileReader fileReader = new YAMLBasedConfigFileReader(TestUtils.getResourcePath("conf",
"envconfigoverride.yaml").get());
Expand All @@ -417,7 +417,7 @@ public void yamlConfigOverrideWithEnvVariable() throws ConfigurationException {
@Test(description = "Tests the functionality when deployment configuration is overridden with system properties")
public void yamlConfigOverrideWithSystemProperty() throws ConfigurationException {
String newTenantName = "NewTenant";
String systemProperty = CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR + "TENANT";
String systemProperty = CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR + "TENANT";
System.setProperty(systemProperty, newTenantName);
ConfigFileReader fileReader = new YAMLBasedConfigFileReader(TestUtils.getResourcePath("conf",
"envconfigoverride.yaml").get());
Expand All @@ -432,7 +432,7 @@ public void yamlConfigOverrideWithSystemProperty() throws ConfigurationException
public void yamlConfigOverrideSystemVarPriorityTest() throws ConfigurationException {
String systemPropertyTenantName = "SystemPropertyTenant";
String environmentVariableTenantName = "EnvironmentVariableTenant";
String systemVariable = CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR + "TENANT";
String systemVariable = CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR + "TENANT";

EnvironmentUtils.setEnvironmentVariables(systemVariable, environmentVariableTenantName);
System.setProperty(systemVariable, systemPropertyTenantName);
Expand Down Expand Up @@ -481,11 +481,16 @@ public void yamlConfigOverrideWithEnvVariablesArray() throws ConfigurationExcept
String transport1Desc = "Transport 1 description";
String transport1Password = "password";

String transport1NameEnv = CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR + "TRANSPORTS_TRANSPORT_0_NAME";
String transport1PortEnv = CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR + "TRANSPORTS_TRANSPORT_0_PORT";
String transport1SecureEnv = CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR + "TRANSPORTS_TRANSPORT_0_SECURE";
String transport1DescEnv = CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR + "TRANSPORTS_TRANSPORT_0_DESC";
String transport1PasswordEnv = CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR + "TRANSPORTS_TRANSPORT_0_PASSWORD";
String transport1NameEnv = CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR +
"TRANSPORTS_TRANSPORT_0_NAME";
String transport1PortEnv = CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR +
"TRANSPORTS_TRANSPORT_0_PORT";
String transport1SecureEnv = CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR +
"TRANSPORTS_TRANSPORT_0_SECURE";
String transport1DescEnv = CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR +
"TRANSPORTS_TRANSPORT_0_DESC";
String transport1PasswordEnv = CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR +
"TRANSPORTS_TRANSPORT_0_PASSWORD";
EnvironmentUtils.setEnvironmentVariables(transport1NameEnv, transport1Name);
EnvironmentUtils.setEnvironmentVariables(transport1PortEnv, String.valueOf(transport1Port));
EnvironmentUtils.setEnvironmentVariables(transport1SecureEnv, transport1Secure);
Expand All @@ -496,8 +501,10 @@ public void yamlConfigOverrideWithEnvVariablesArray() throws ConfigurationExcept
String transport2Name = "pqr";
String transport2password = "transport2password";

String transport2NameEnv = CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR + "TRANSPORTS_TRANSPORT_8_NAME";
String transport2PasswordEnv = CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR + "TRANSPORTS_TRANSPORT_8_PASSWORD";
String transport2NameEnv = CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR +
"TRANSPORTS_TRANSPORT_8_NAME";
String transport2PasswordEnv = CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR +
"TRANSPORTS_TRANSPORT_8_PASSWORD";
EnvironmentUtils.setEnvironmentVariables(transport2NameEnv, transport2Name);
EnvironmentUtils.setEnvironmentVariables(transport2PasswordEnv, transport2password);

Expand Down Expand Up @@ -547,7 +554,7 @@ public void invalidEnvVariableFormatsTest() throws ConfigurationException {
String invalidEnvVar1 = CONFIG_LEVEL_SEPARATOR;
String invalidEnvVar2 = CONFIG_NAMESPACE;
String invalidEnvVar3 = CONFIG_LEVEL_SEPARATOR + CONFIG_NAMESPACE;
String invalidEnvVar4 = CONFIG_LEVEL_SEPARATOR + CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR;
String invalidEnvVar4 = CONFIG_LEVEL_SEPARATOR + CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR;
String invalidEnvVar5 = CONFIG_LEVEL_SEPARATOR + CONFIG_LEVEL_SEPARATOR + CONFIG_LEVEL_SEPARATOR;
String invalidEnvVar6 = CONFIG_LEVEL_SEPARATOR + CONFIG_LEVEL_SEPARATOR + "config";

Expand All @@ -574,9 +581,10 @@ public void invalidEnvVariableFormatsTest() throws ConfigurationException {
@Test(description = "Tests invalid fields in environment variable")
public void envInvalidFieldTest() throws ConfigurationException {
boolean isExceptionOccurred = false;
String transportNameEnv = CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR + "TRANSPORTS_TRANSPORT_0_NAME";
String transportInvalidAttributeEnv = CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR +
"TRANSPORTS_TRANSPORT_0_INVALIDATTRIBUTE";
String transportNameEnv = CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR +
"TRANSPORTS_TRANSPORT_0_NAME";
String transportInvalidAttributeEnv = CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR +
"TRANSPORTS_TRANSPORT_0_INVALIDATTRIBUTE";

EnvironmentUtils.setEnvironmentVariables(transportNameEnv, "abc");
EnvironmentUtils.setEnvironmentVariables(transportInvalidAttributeEnv, "INVALID");
Expand All @@ -603,9 +611,10 @@ public void envInvalidFieldTest() throws ConfigurationException {
@Test(description = "Tests expected exception when an invalid value is set to a field")
public void envFieldValueCastExceptionTest() throws ConfigurationException {
boolean isExceptionOccurred = false;
String transportNameEnv = CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR + "TRANSPORTS_TRANSPORT_0_NAME";
String transportInvalidPortEnv = CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR +
"TRANSPORTS_TRANSPORT_0_PORT";
String transportNameEnv = CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR +
"TRANSPORTS_TRANSPORT_0_NAME";
String transportInvalidPortEnv = CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR +
"TRANSPORTS_TRANSPORT_0_PORT";

EnvironmentUtils.setEnvironmentVariables(transportNameEnv, "abc");
EnvironmentUtils.setEnvironmentVariables(transportInvalidPortEnv, "INVALID");
Expand All @@ -631,7 +640,8 @@ public void envFieldValueCastExceptionTest() throws ConfigurationException {
@Test(description = "Tests setting array element value failure when the unique element is not located")
public void envArrayNoUniqueElementTest() {
boolean isExceptionOccurred = false;
String transportPortEnv = CONFIG_NAMESPACE + CONFIG_LEVEL_SEPARATOR + "TRANSPORTS_TRANSPORT_0_PORT";
String transportPortEnv = CONFIG_NAMESPACE.toUpperCase() + CONFIG_LEVEL_SEPARATOR +
"TRANSPORTS_TRANSPORT_0_PORT";

EnvironmentUtils.setEnvironmentVariables(transportPortEnv, "INVALID");

Expand All @@ -644,9 +654,8 @@ public void envArrayNoUniqueElementTest() {
} catch (ConfigurationException e) {
isExceptionOccurred = true;
Assert.assertEquals(e.getMessage(), "Locating unique system variable key for system variable " +
transportPortEnv + " from default attributes [ID, NAME] failed. " +
"Custom unique system variable key testconfiguration_TRANSPORTS_" +
"TRANSPORT_UNIQUE is not specified as well.");
transportPortEnv + " from default attributes [ID, NAME] failed. " + "Custom unique system " +
"variable key TESTCONFIGURATION_TRANSPORTS_" + "TRANSPORT_UNIQUE is not specified as well.");
} finally {
EnvironmentUtils.unsetEnvironmentVariables(transportPortEnv);
}
Expand Down Expand Up @@ -759,6 +768,21 @@ public void envSetUniqueElementSystemVarPriorityTest() throws ConfigurationExcep
System.clearProperty(customUniqueVar);
}

@Test(description = "Tests the functionality when deployment configuration is overridden with environment " +
"variables with complex namespace")
public void yamlConfigOverrideWithComplexNameSpaceEnvVariable() throws ConfigurationException {
String newTenantName = "NewTenant";
String envVariable = "WSO2_TEST_CONFIG" + CONFIG_LEVEL_SEPARATOR + "TENANT";
EnvironmentUtils.setEnvironmentVariables(envVariable, newTenantName);
ConfigFileReader fileReader = new YAMLBasedConfigFileReader(TestUtils.getResourcePath("conf",
"complexnamespaceconfig.yaml").get());
ConfigProvider configProvider = new ConfigProviderImpl(fileReader, secureVault);
ComplexNameSpaceConfiguration configurations = configProvider.getConfigurationObject
(ComplexNameSpaceConfiguration.class);
Assert.assertEquals(configurations.getTenant(), newTenantName);
EnvironmentUtils.unsetEnvironmentVariables(envVariable);
}

/**
* Set environmental variables.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
wso2.test.config:
tenant: tenant
transports:
transport: #Transport with direct values
- name: abc
port: 8000
secure: false
desc: This transport will use 8000 as its port
password: ${sec:conn.auth.password}
- name: pqr
port: ${env:pqr.http.port}
secure: ${sys:pqr.secure}
desc: This transport will use ${env:pqr.http.port} as its port. Secure - ${sys:pqr.secure}
- name: xyz
port: ${env:xyz.http.port,9000}
secure: ${sys:xyz.secure,true}
desc: This transport will use ${env:xyz.http.port,8888} as its port

# TESTCONFIGURATION_TENANT="tenant"
# TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_NAME="abc"
# TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_PORT="8000"
# TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_SECURE="false"
# TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_DESC="This transport will use 8000 as its port"
# TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_PASSWORD="${sec:conn.auth.password}"

# TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_NAME="pqr"
# TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_PORT="${env:pqr.http.port}"
# TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_SECURE="${sys:pqr.secure}"
# TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_DESC="This transport will use ${env:pqr.http.port} as its port. Secure - ${sys:pqr.secure}"

# TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_NAME="xyz"
# TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_PORT="${env:xyz.http.port,9000}"
# TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_SECURE="${sys:xyz.secure,true}"
# TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_DESC="This transport will use ${env:xyz.http.port,8888} as its port"
4 changes: 2 additions & 2 deletions docs/ConfigurationsViaEnvironmentVariables.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ wso2.configuration:
The above configuration can be represented with the below environment variables / system properties:

```bash
WSO2.CONFIGURATION_COMPLEXTESTBEAN_NAME="default"
WSO2.CONFIGURATION_COMPLEXTESTBEAN_BEAN_NAME="default"
WSO2_CONFIGURATION_COMPLEXTESTBEAN_NAME="default"
WSO2_CONFIGURATION_COMPLEXTESTBEAN_BEAN_NAME="default"
```

Where,
Expand Down

0 comments on commit 6d34c4d

Please sign in to comment.