├── .gitignore ├── components └── org.wso2.carbon.config │ ├── src │ ├── main │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── javax.annotation.processing.Processor │ │ └── java │ │ │ └── org │ │ │ └── wso2 │ │ │ └── carbon │ │ │ └── config │ │ │ ├── ConfigurationException.java │ │ │ ├── annotation │ │ │ ├── Ignore.java │ │ │ ├── Element.java │ │ │ └── Configuration.java │ │ │ ├── ConfigurationRuntimeException.java │ │ │ ├── reader │ │ │ ├── YAMLBasedConfigFileReader.java │ │ │ ├── ConfigFileReader.java │ │ │ └── YmlMerger.java │ │ │ ├── ConfigConstants.java │ │ │ ├── provider │ │ │ ├── ConfigProvider.java │ │ │ └── ImmutablePair.java │ │ │ ├── ConfigurationProcessor.java │ │ │ ├── internal │ │ │ └── ConfigProviderComponent.java │ │ │ ├── ConfigProviderFactory.java │ │ │ └── ConfigurationUtils.java │ └── test │ │ ├── resources │ │ ├── conf │ │ │ ├── wso2carbon.jks │ │ │ ├── master-keys.yaml │ │ │ ├── secrets.properties │ │ │ ├── envconfigoverridecomplex.yaml │ │ │ ├── deployment.yaml │ │ │ ├── envconfigwithoutdefaults.yaml │ │ │ ├── invalidconfiguration.yaml │ │ │ ├── systemconfigwithoutdefaults.yaml │ │ │ ├── Example2.yaml │ │ │ ├── envconfigoverrideuniqueelement.yaml │ │ │ ├── envconfigoverridepriority.yaml │ │ │ ├── Example.txt │ │ │ ├── Example.xml │ │ │ ├── Example.yaml │ │ │ ├── envconfigoverride.yaml │ │ │ ├── complexnamespaceconfig.yaml │ │ │ └── sampledatasource.yaml │ │ └── testng.xml │ │ └── java │ │ └── org │ │ └── wso2 │ │ └── carbon │ │ └── config │ │ ├── configprovider │ │ ├── BaseConfiguration.java │ │ ├── ComplexNameSpaceConfiguration.java │ │ ├── TestUtils.java │ │ ├── BasicTestConfiguration.java │ │ ├── PriorityTestConfiguration.java │ │ ├── UniqueElementTestConfiguration.java │ │ ├── TestTransportConfiguration2.java │ │ ├── TestConfiguration.java │ │ └── ConfigProviderFactoryTest.java │ │ ├── utils │ │ └── EnvironmentUtils.java │ │ └── UtilsTest.java │ └── pom.xml ├── docs ├── images │ └── ConfigurationsViaEnvironmentVariables │ │ ├── VarStructure.png │ │ └── SysVarPriority.png ├── InstallingConfigFeature.md └── ConfigurationsViaEnvironmentVariables.md ├── samples ├── config-provider │ ├── standalone │ │ ├── src │ │ │ └── main │ │ │ │ ├── resources │ │ │ │ ├── conf │ │ │ │ │ ├── master-keys.yaml │ │ │ │ │ ├── secrets.properties │ │ │ │ │ └── deployment.yaml │ │ │ │ ├── security │ │ │ │ │ └── wso2carbon.jks │ │ │ │ └── log4j.properties │ │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── wso2 │ │ │ │ └── carbon │ │ │ │ └── config │ │ │ │ └── samples │ │ │ │ └── standalone │ │ │ │ └── Application.java │ │ ├── assembly.xml │ │ ├── README.md │ │ └── pom.xml │ └── osgi-bundle │ │ ├── README.md │ │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── org │ │ │ └── wso2 │ │ │ └── carbon │ │ │ └── config │ │ │ └── samples │ │ │ └── bundle │ │ │ ├── ChildConfiguration.java │ │ │ ├── ParentConfiguration.java │ │ │ └── internal │ │ │ └── ConfigurationServiceComponent.java │ │ └── pom.xml └── config-generator │ ├── src │ └── main │ │ └── java │ │ └── org │ │ └── wso2 │ │ └── carbon │ │ └── config │ │ └── samples │ │ ├── ChildConfiguration.java │ │ └── ParentConfiguration.java │ ├── pom.xml │ └── README.md ├── extensions └── org.wso2.carbon.config.maven.plugin │ ├── src │ └── main │ │ ├── resources │ │ └── LICENSE.txt │ │ └── java │ │ └── org │ │ └── wso2 │ │ └── carbon │ │ └── config │ │ └── maven │ │ └── plugin │ │ └── exceptions │ │ └── ConfigurationMavenRuntimeException.java │ └── pom.xml ├── issue_template.md ├── findbugs-exclude.xml ├── tests ├── org.wso2.carbon.config.test │ ├── src │ │ └── test │ │ │ ├── resources │ │ │ └── testng.xml │ │ │ └── java │ │ │ └── org │ │ │ └── wso2 │ │ │ └── carbon │ │ │ └── config │ │ │ └── test │ │ │ └── annotationprocessor │ │ │ ├── TestConfiguration.java │ │ │ └── AnnotationProcessorTest.java │ └── pom.xml └── org.wso2.carbon.config.test.coverage │ └── pom.xml ├── pull_request_template.md ├── features └── org.wso2.carbon.config.feature │ └── pom.xml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .settings 4 | .project 5 | *.iml 6 | *.iws 7 | *.ipr 8 | .idea 9 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/resources/META-INF/services/javax.annotation.processing.Processor: -------------------------------------------------------------------------------- 1 | org.wso2.carbon.config.ConfigurationProcessor -------------------------------------------------------------------------------- /docs/images/ConfigurationsViaEnvironmentVariables/VarStructure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wso2/carbon-config/master/docs/images/ConfigurationsViaEnvironmentVariables/VarStructure.png -------------------------------------------------------------------------------- /docs/images/ConfigurationsViaEnvironmentVariables/SysVarPriority.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wso2/carbon-config/master/docs/images/ConfigurationsViaEnvironmentVariables/SysVarPriority.png -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/wso2carbon.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wso2/carbon-config/master/components/org.wso2.carbon.config/src/test/resources/conf/wso2carbon.jks -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/master-keys.yaml: -------------------------------------------------------------------------------- 1 | permanent: true 2 | masterKeys: 3 | keyStorePassword: !!binary d3NvMmNhcmJvbg== 4 | privateKeyPassword: !!binary d3NvMmNhcmJvbg== -------------------------------------------------------------------------------- /samples/config-provider/standalone/src/main/resources/conf/master-keys.yaml: -------------------------------------------------------------------------------- 1 | permanent: true 2 | masterKeys: 3 | keyStorePassword: !!binary d3NvMmNhcmJvbg== 4 | privateKeyPassword: !!binary d3NvMmNhcmJvbg== -------------------------------------------------------------------------------- /samples/config-provider/standalone/src/main/resources/security/wso2carbon.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wso2/carbon-config/master/samples/config-provider/standalone/src/main/resources/security/wso2carbon.jks -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/secrets.properties: -------------------------------------------------------------------------------- 1 | wso2.sample.password1=plainText ABC@123 2 | wso2.sample.password2=cipherText SnBSWKjtZZOo0UsmOpPRhP6ZMNYTb80+BZHRDC/kxNT9ExcTswAbFjb/aip2KgQNaVuIT27UtrBaIv77Mb5sNPGiwyPrfajLNhSOlke2p8YmMkegx/mG2ytJhJa5j9iMGtCsbMt+SAf85v6kGIiH0gZA20qDZ9jnveT7/Ifz7v0\= 3 | -------------------------------------------------------------------------------- /samples/config-provider/standalone/src/main/resources/conf/secrets.properties: -------------------------------------------------------------------------------- 1 | wso2.sample.password1=plainText ABC@123 2 | wso2.sample.password2=cipherText SnBSWKjtZZOo0UsmOpPRhP6ZMNYTb80+BZHRDC/kxNT9ExcTswAbFjb/aip2KgQNaVuIT27UtrBaIv77Mb5sNPGiwyPrfajLNhSOlke2p8YmMkegx/mG2ytJhJa5j9iMGtCsbMt+SAf85v6kGIiH0gZA20qDZ9jnveT7/Ifz7v0\= 3 | -------------------------------------------------------------------------------- /samples/config-provider/standalone/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=info, stdout 2 | 3 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 4 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 5 | 6 | # Pattern to output the caller's file name and line number. 7 | log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n 8 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/envconfigoverridecomplex.yaml: -------------------------------------------------------------------------------- 1 | basictestconfiguration: 2 | testBean: 3 | name: default 4 | complexTestBean: 5 | name: default 6 | testBean: 7 | name: default 8 | 9 | # BASICTESTCONFIGURATION_TESTBEAN_NAME="default" 10 | # BASICTESTCONFIGURATION_COMPLEXTESTBEAN_NAME="default" 11 | # BASICTESTCONFIGURATION_COMPLEXTESTBEAN_TESTBEAN_NAME="default" -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/deployment.yaml: -------------------------------------------------------------------------------- 1 | wso2.securevault: 2 | secretRepository: 3 | type: org.wso2.carbon.secvault.repository.DefaultSecretRepository 4 | parameters: 5 | privateKeyAlias: wso2carbon 6 | keystoreLocation: ${sys:keystore.file} 7 | secretPropertiesFile: ${sys:sec.prop.file} 8 | masterKeyReader: 9 | type: org.wso2.carbon.secvault.reader.DefaultMasterKeyReader 10 | parameters: 11 | masterKeyReaderFile: ${sys:master.key.file} 12 | 13 | testconfiguration: 14 | tenant: tenant 15 | transports: 16 | transport: #Transport with direct values 17 | - name: abc 18 | port: 8000 19 | secure: false -------------------------------------------------------------------------------- /extensions/org.wso2.carbon.config.maven.plugin/src/main/resources/LICENSE.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) %s, WSO2 Inc. (http://www.wso2.org) All Rights Reserved 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the \"License\"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an \"AS IS\" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/envconfigwithoutdefaults.yaml: -------------------------------------------------------------------------------- 1 | testconfiguration: 2 | tenant: tenant 3 | transports: 4 | transport: #Transport with direct values 5 | - name: abc 6 | port: 8000 7 | secure: false 8 | desc: This transport will use 8000 as its port 9 | password: ${sec:conn.auth.password} 10 | - name: pqr 11 | port: ${env:pqr.http.port} 12 | secure: ${sys:pqr.secure} 13 | desc: This transport will use ${env:pqr.http.port} as its port. Secure - ${sys:pqr.secure} 14 | - name: xyz 15 | port: ${env:xyz.http.port} 16 | secure: ${sys:xyz.secure,true} 17 | desc: This transport will use ${env:xyz.http.port} as its port -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/invalidconfiguration.yaml: -------------------------------------------------------------------------------- 1 | testconfiguration1: 2 | tenant: tenant 3 | transports: 4 | transport: #Transport with direct values 5 | - name: abc 6 | port: 8000 7 | secure: false 8 | desc: This transport will use 8000 as its port 9 | password: ${sec:conn.auth.password} 10 | - name: pqr 11 | port: ${env:pqr.http.port} 12 | secure: ${sys:pqr.secure} 13 | desc: This transport will use ${env:pqr.http.port} as its port. Secure - ${sys:pqr.secure} 14 | - name: xyz 15 | port: ${env:xyz.http.port,9000} 16 | secure: ${sys:xyz.secure,true} 17 | desc: This transport will use ${env:xyz.http.port,8888} as its port -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/systemconfigwithoutdefaults.yaml: -------------------------------------------------------------------------------- 1 | testconfiguration: 2 | tenant: tenant 3 | transports: 4 | transport: #Transport with direct values 5 | - name: abc 6 | port: 8000 7 | secure: false 8 | desc: This transport will use 8000 as its port 9 | password: ${sec:conn.auth.password} 10 | - name: pqr 11 | port: ${env:pqr.http.port} 12 | secure: ${sys:pqr.secure} 13 | desc: This transport will use ${env:pqr.http.port} as its port. Secure - ${sys:pqr.secure} 14 | - name: xyz 15 | port: ${env:xyz.http.port,9000} 16 | secure: ${sys:xyz.secure} 17 | desc: This transport will use ${env:xyz.http.port,8888} as its port -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/Example2.yaml: -------------------------------------------------------------------------------- 1 | testTransports: 2 | - testTransport: 3 | name: abc 4 | port: 9090 5 | secure: true 6 | desc: This transport will use 8000 as its port 7 | password: ${sec:conn.auth.password} 8 | - testTransport: 9 | name: pqrs 10 | port: ${env:pqr.http.port} 11 | secure: ${sys:pqr.secure} 12 | desc: This transport will use ${env:pqr.http.port} as its port. Secure - ${sys:pqr.secure} 13 | - testTransport: 14 | name: xyz 15 | port: ${env:xyz.http.port,9000} 16 | secure: ${sys:xyz.secure,true} 17 | desc: This transport will use ${env:xyz.http.port,8888} as its port 18 | 19 | nonamespace.configuration: 20 | name: transport 21 | testBean: 22 | id: 30 -------------------------------------------------------------------------------- /issue_template.md: -------------------------------------------------------------------------------- 1 | **Description:** 2 | 3 | 4 | **Suggested Labels:** 5 | 6 | 7 | **Suggested Assignees:** 8 | 9 | 10 | **Affected Product Version:** 11 | 12 | **OS, DB, other environment details and versions:** 13 | 14 | **Steps to reproduce:** 15 | 16 | 17 | **Related Issues:** 18 | -------------------------------------------------------------------------------- /findbugs-exclude.xml: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/envconfigoverrideuniqueelement.yaml: -------------------------------------------------------------------------------- 1 | uniqueelementtestconfiguration: 2 | uniqueElementTestBeans: 3 | uniqueElementTestBeanList: 4 | - uniqueElement: abc 5 | port: 8000 6 | - uniqueElement: pqr 7 | port: 9000 8 | - uniqueElement: xyz 9 | port: 7000 10 | 11 | # UNIQUEELEMENTTESTCONFIGURATION_UNIQUEELEMENTTESTBEANS_UNIQUEELEMENTTESTBEANLIST_0_UNIQUEELEMENT="abc" 12 | # UNIQUEELEMENTTESTCONFIGURATION_UNIQUEELEMENTTESTBEANS_UNIQUEELEMENTTESTBEANLIST_0_PORT="8000" 13 | 14 | # UNIQUEELEMENTTESTCONFIGURATION_UNIQUEELEMENTTESTBEANS_UNIQUEELEMENTTESTBEANLIST_1_UNIQUEELEMENT="pqr" 15 | # UNIQUEELEMENTTESTCONFIGURATION_UNIQUEELEMENTTESTBEANS_UNIQUEELEMENTTESTBEANLIST_1_PORT="9000" 16 | 17 | # UNIQUEELEMENTTESTCONFIGURATION_UNIQUEELEMENTTESTBEANS_UNIQUEELEMENTTESTBEANLIST_2_UNIQUEELEMENT="xyz" 18 | # UNIQUEELEMENTTESTCONFIGURATION_UNIQUEELEMENTTESTBEANS_UNIQUEELEMENTTESTBEANLIST_2_PORT="7000" -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/envconfigoverridepriority.yaml: -------------------------------------------------------------------------------- 1 | prioritytestconfiguration: 2 | testBeans: 3 | testBeanList: 4 | - name: abc 5 | id: 1 6 | port: 8000 7 | - name: pqr 8 | id: 2 9 | port: ${env:pqr.http.port} 10 | - name: xyz 11 | id: 3 12 | port: ${env:xyz.http.port,9000} 13 | 14 | # PRIORITYTESTCONFIGURATION_TESTBEANS_TESTBEANLIST_0_NAME="abc" 15 | # PRIORITYTESTCONFIGURATION_TESTBEANS_TESTBEANLIST_0_ID="1" 16 | # PRIORITYTESTCONFIGURATION_TESTBEANS_TESTBEANLIST_0_PORT="8000" 17 | 18 | # PRIORITYTESTCONFIGURATION_TESTBEANS_TESTBEANLIST_1_NAME="pqr" 19 | # PRIORITYTESTCONFIGURATION_TESTBEANS_TESTBEANLIST_1_ID="2" 20 | # PRIORITYTESTCONFIGURATION_TESTBEANS_TESTBEANLIST_1_PORT="${env:pqr.http.port}" 21 | 22 | # PRIORITYTESTCONFIGURATION_TESTBEANS_TESTBEANLIST_2_NAME="xyz" 23 | # PRIORITYTESTCONFIGURATION_TESTBEANS_TESTBEANLIST_2_ID="3" 24 | # PRIORITYTESTCONFIGURATION_TESTBEANS_TESTBEANLIST_2_PORT="${env:xyz.http.port,9000}" -------------------------------------------------------------------------------- /tests/org.wso2.carbon.config.test/src/test/resources/testng.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/config-provider/standalone/assembly.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | jar-with-dependencies 19 | 20 | jar 21 | 22 | false 23 | 24 | 25 | / 26 | true 27 | runtime 28 | 29 | 30 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/Example.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | tenant 4 | 5 | 6 | 7 | abc 8 | 8000 9 | This transport will use 8000 as its port 10 | ${sec:conn.auth.password} 11 | 12 | 13 | 14 | pqr 15 | ${env:pqr.http.port} 16 | This transport will use ${env:pqr.http.port} as its port. Secure - ${sys:pqr.secure} 17 | 18 | 19 | 20 | xyz 21 | ${sys:xyz.http.port,9000} 22 | This transport will use ${env:xyz.http.port,8888} as its port 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/Example.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | tenant 4 | 5 | 6 | 7 | abc 8 | 8000 9 | This transport will use 8000 as its port 10 | ${sec:conn.auth.password} 11 | 12 | 13 | 14 | pqr 15 | ${env:pqr.http.port} 16 | This transport will use ${env:pqr.http.port} as its port. Secure - ${sys:pqr.secure} 17 | 18 | 19 | 20 | xyz 21 | ${sys:xyz.http.port,9000} 22 | This transport will use ${env:xyz.http.port,8888} as its port 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/java/org/wso2/carbon/config/ConfigurationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config; 17 | 18 | /** 19 | * ConfigurationException throws when server cannot provide the configuration. 20 | * 21 | * @since 1.0.0 22 | */ 23 | public class ConfigurationException extends Exception { 24 | 25 | public ConfigurationException(String message) { 26 | super(message); 27 | } 28 | 29 | public ConfigurationException(String message, Throwable cause) { 30 | super(message, cause); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /extensions/org.wso2.carbon.config.maven.plugin/src/main/java/org/wso2/carbon/config/maven/plugin/exceptions/ConfigurationMavenRuntimeException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.carbon.config.maven.plugin.exceptions; 19 | 20 | /** 21 | * Exception class to interpret runtime exceptions when preparing the configuration. 22 | * 23 | * @since 1.0.0 24 | */ 25 | public class ConfigurationMavenRuntimeException extends RuntimeException { 26 | 27 | public ConfigurationMavenRuntimeException(String message, Throwable cause) { 28 | super(message, cause); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/java/org/wso2/carbon/config/annotation/Ignore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | /** 24 | * Field level annotation for configuration tool. 25 | * annotated fields will not go to the configuration file. 26 | * 27 | * @since 1.0.0 28 | */ 29 | @Retention(RetentionPolicy.RUNTIME) 30 | @Target(ElementType.FIELD) 31 | public @interface Ignore { 32 | } 33 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/testng.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/java/org/wso2/carbon/config/ConfigurationRuntimeException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.carbon.config; 19 | 20 | /** 21 | * Configuration runtime exception when error on providing configuration during the runtime. 22 | * 23 | * @since 1.0.0 24 | */ 25 | public class ConfigurationRuntimeException extends RuntimeException { 26 | 27 | public ConfigurationRuntimeException(String message) { 28 | super(message); 29 | } 30 | 31 | public ConfigurationRuntimeException(String message, Throwable cause) { 32 | super(message, cause); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/java/org/wso2/carbon/config/annotation/Element.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | /** 24 | * Field level annotation for configuration tool. 25 | * description : required, field comment 26 | * required : optional, only for the required field 27 | * 28 | * @since 1.0.0 29 | */ 30 | @Retention(RetentionPolicy.RUNTIME) 31 | @Target(ElementType.FIELD) 32 | public @interface Element { 33 | // field description, required 34 | String description(); 35 | 36 | boolean required() default false; 37 | } 38 | -------------------------------------------------------------------------------- /samples/config-provider/standalone/README.md: -------------------------------------------------------------------------------- 1 | # Carbon Configuration - OSGi Sample 2 | 3 | ### Building the configuration 4 | 5 | Navigate to [Config Generator Sample](../config-generator) 6 | and [Config Standalone Sample](/) locations respectively and execute the command 7 | below: 8 | 9 | ```bash 10 | mvn clean install 11 | ``` 12 | 13 | ### Running the sample 14 | 15 | * Navigate to [Target folder](/target) 16 | * Execute `java -jar provider-standalone-{version}.jar 17 | ` 18 | 19 | Now you will notice the `Parent configuration - name : WSO2, value : 10, childConfiguration - destination : destination-name, isEnabled : false` 20 | log message. 21 | 22 | You can override the parent configuration values using the deployment.yaml configuration. 23 | In order to do so add the configurations you want to change under the `"wso2.configuration"` 24 | namespace is deployment.yaml. 25 | 26 | **Example deployment.yaml** 27 | 28 | ```yaml 29 | # Carbon Configuration Parameters 30 | wso2.carbon: 31 | # value to uniquely identify a server 32 | id: carbon-kernel 33 | # server name 34 | name: WSO2 Carbon Kernel 35 | # ports used by this server 36 | ports: 37 | # port offset 38 | offset: 0 39 | 40 | wso2.configuration: 41 | name: "SomeName" 42 | ``` 43 | 44 | The above configuration will give the below output: 45 | `Parent configuration - name : SomeName, value : 10, childConfiguration - destination : destination-name, isEnabled : false` -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/Example.yaml: -------------------------------------------------------------------------------- 1 | testconfiguration: 2 | tenant: tenant 3 | transports: 4 | transport: #Transport with direct values 5 | - name: abc 6 | port: 8000 7 | secure: false 8 | desc: This transport will use 8000 as its port 9 | password: ${sec:conn.auth.password} 10 | - name: pqr 11 | port: ${env:pqr.http.port} 12 | secure: ${sys:pqr.secure} 13 | desc: This transport will use ${env:pqr.http.port} as its port. Secure - ${sys:pqr.secure} 14 | - name: xyz 15 | port: ${env:xyz.http.port,9000} 16 | secure: ${sys:xyz.secure,true} 17 | desc: This transport will use ${env:xyz.http.port,8888} as its port 18 | 19 | testconfiguration.v2: 20 | tenant: tenant 21 | transports: 22 | transport: #Transport with direct values 23 | - name: abc 24 | port: 9090 25 | secure: true 26 | desc: This transport will use 8000 as its port 27 | password: ${sec:conn.auth.password} 28 | - name: pqrs 29 | port: ${env:pqr.http.port} 30 | secure: ${sys:pqr.secure} 31 | desc: This transport will use ${env:pqr.http.port} as its port. Secure - ${sys:pqr.secure} 32 | - name: xyz 33 | port: ${env:xyz.http.port,9000} 34 | secure: ${sys:xyz.secure,true} 35 | desc: This transport will use ${env:xyz.http.port,8888} as its port 36 | 37 | nonamespace.configuration: 38 | name: transport 39 | testBean: 40 | id: 30 41 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/java/org/wso2/carbon/config/configprovider/BaseConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config.configprovider; 17 | 18 | /** 19 | * Sample configuration class for testing purposes. 20 | *

21 | * This is to test generating configuration for beans without namespace. 22 | * 23 | * @since 2.1.3 24 | */ 25 | public class BaseConfiguration { 26 | private String name = "test"; 27 | private BaseTestBean testBean = new BaseTestBean(); 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public BaseTestBean getTestBean() { 34 | return testBean; 35 | } 36 | } 37 | 38 | /** 39 | * Sample configuration class for testing purposes. 40 | */ 41 | class BaseTestBean { 42 | private int id = 20; 43 | 44 | public int getId() { 45 | return id; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /samples/config-provider/osgi-bundle/README.md: -------------------------------------------------------------------------------- 1 | # Carbon Configuration - OSGi Bundle Sample 2 | 3 | ### Building the configuration 4 | 5 | Navigate to [Config OSGi Sample](/) location and execute the command 6 | below: 7 | 8 | ```bash 9 | mvn clean install 10 | ``` 11 | 12 | ### Running the sample 13 | 14 | * Download Carbon Kernel 5.2.0 from [http://wso2.com/products/carbon/](http://wso2.com/products/carbon/) 15 | * Copy provider-bundle-{version}.jar in [Config OSGi Sample](/target) to /lib location 16 | * Start the WSO2 Carbon Server by executing /bin/carbon.sh script 17 | 18 | Now you will notice the `Parent configuration - name : WSO2, value : 10, childConfiguration - destination : destination-name, isEnabled : false` 19 | log message. 20 | 21 | You can override the parent configuration values using the deployment.yaml configuration. In order to do so add the 22 | configurations you want to change under the `"wso2.configuration"` namespace is deployment.yaml. 23 | 24 | **Example deployment.yaml** 25 | 26 | ```yaml 27 | # Carbon Configuration Parameters 28 | wso2.carbon: 29 | # value to uniquely identify a server 30 | id: carbon-kernel 31 | # server name 32 | name: WSO2 Carbon Kernel 33 | # ports used by this server 34 | ports: 35 | # port offset 36 | offset: 0 37 | 38 | wso2.configuration: 39 | name: "SomeName" 40 | ``` 41 | 42 | The above configuration will give the below output: 43 | `Parent configuration - name : SomeName, value : 10, childConfiguration - destination : destination-name, isEnabled : false` -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/java/org/wso2/carbon/config/annotation/Configuration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config.annotation; 17 | 18 | import org.wso2.carbon.config.ConfigConstants; 19 | 20 | import java.lang.annotation.ElementType; 21 | import java.lang.annotation.Retention; 22 | import java.lang.annotation.RetentionPolicy; 23 | import java.lang.annotation.Target; 24 | 25 | /** 26 | * Class level annotation for configuration tool. 27 | * namespace : optional, required only for root configuration classes 28 | * description : required, field comment 29 | * 30 | * @since 1.0.0 31 | */ 32 | @Retention(RetentionPolicy.RUNTIME) 33 | @Target(ElementType.TYPE) 34 | public @interface Configuration { 35 | 36 | // needed only for root configuration bean 37 | String namespace() default ConfigConstants.NULL; 38 | 39 | // field description, required 40 | String description(); 41 | } 42 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/java/org/wso2/carbon/config/reader/YAMLBasedConfigFileReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config.reader; 17 | 18 | import org.wso2.carbon.config.ConfigurationException; 19 | import org.wso2.carbon.config.ConfigurationUtils; 20 | 21 | import java.nio.file.Path; 22 | import java.util.Map; 23 | 24 | /** 25 | * This class takes care of parsing the deployment.yaml file and creating the deployment configuration table. 26 | * 27 | * @since 1.0.0 28 | */ 29 | public class YAMLBasedConfigFileReader extends ConfigFileReader { 30 | 31 | public YAMLBasedConfigFileReader(Path configurationFilePath) { 32 | super(configurationFilePath); 33 | } 34 | 35 | @Override 36 | public Map getDeploymentConfiguration() throws ConfigurationException { 37 | String yamlFileString = getFileContent(); 38 | return ConfigurationUtils.getDeploymentConfigMap(yamlFileString); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /samples/config-provider/standalone/src/main/resources/conf/deployment.yaml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the \"License\"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an \"AS IS\" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ################################################################################ 16 | 17 | # Carbon Configuration Parameters 18 | wso2.carbon: 19 | # value to uniquely identify a server 20 | id: carbon-kernel 21 | # server name 22 | name: WSO2 Carbon Kernel 23 | # ports used by this server 24 | ports: 25 | # port offset 26 | offset: 0 27 | 28 | wso2.securevault: 29 | secretRepository: 30 | type: org.wso2.carbon.secvault.repository.DefaultSecretRepository 31 | parameters: 32 | privateKeyAlias: wso2carbon 33 | keystoreLocation: resources/security/wso2carbon.jks 34 | secretPropertiesFile: resources/conf/secrets.properties 35 | masterKeyReader: 36 | type: org.wso2.carbon.secvault.reader.DefaultMasterKeyReader 37 | parameters: 38 | masterKeyReaderFile: resources/conf/master-keys.yaml 39 | -------------------------------------------------------------------------------- /docs/InstallingConfigFeature.md: -------------------------------------------------------------------------------- 1 | # Installing Configuration Provider Feature in OSGi 2 | 3 | Configuration Provider feature is depends on **carbon-secvault** feature and **carbon-utils** feature. If we need to install 4 | configuration provider feature, referred P2 repository needs to have both carbon-secvault feature and carbon-utils 5 | feature. So when we are generating P2 repository, we need to add features as below. 6 | 7 | ````xml 8 | 9 | org.wso2.carbon.maven 10 | carbon-feature-plugin 11 | 12 | 13 | p2-repo-generation 14 | package 15 | 16 | generate-repo 17 | 18 | 19 | file:${basedir}/target/p2-repo 20 | 21 | 22 | org.wso2.carbon.config.feature 23 | ${carbon.config.version} 24 | 25 | 26 | org.wso2.carbon.secvault.feature 27 | ${carbon.securevault.version} 28 | 29 | 30 | org.wso2.carbon.utils.feature 31 | ${carbon.utils.version} 32 | 33 | 34 | 35 | 36 | ... 37 | 38 | 39 | ```` 40 | 41 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/envconfigoverride.yaml: -------------------------------------------------------------------------------- 1 | testconfiguration: 2 | tenant: tenant 3 | transports: 4 | transport: #Transport with direct values 5 | - name: abc 6 | port: 8000 7 | secure: false 8 | desc: This transport will use 8000 as its port 9 | password: ${sec:conn.auth.password} 10 | - name: pqr 11 | port: ${env:pqr.http.port} 12 | secure: ${sys:pqr.secure} 13 | desc: This transport will use ${env:pqr.http.port} as its port. Secure - ${sys:pqr.secure} 14 | - name: xyz 15 | port: ${env:xyz.http.port,9000} 16 | secure: ${sys:xyz.secure,true} 17 | desc: This transport will use ${env:xyz.http.port,8888} as its port 18 | 19 | # TESTCONFIGURATION_TENANT="tenant" 20 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_NAME="abc" 21 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_PORT="8000" 22 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_SECURE="false" 23 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_DESC="This transport will use 8000 as its port" 24 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_PASSWORD="${sec:conn.auth.password}" 25 | 26 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_NAME="pqr" 27 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_PORT="${env:pqr.http.port}" 28 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_SECURE="${sys:pqr.secure}" 29 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_DESC="This transport will use ${env:pqr.http.port} as its port. Secure - ${sys:pqr.secure}" 30 | 31 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_NAME="xyz" 32 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_PORT="${env:xyz.http.port,9000}" 33 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_SECURE="${sys:xyz.secure,true}" 34 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_DESC="This transport will use ${env:xyz.http.port,8888} as its port" -------------------------------------------------------------------------------- /samples/config-provider/osgi-bundle/src/main/java/org/wso2/carbon/config/samples/bundle/ChildConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.carbon.config.samples.bundle; 19 | 20 | import org.wso2.carbon.config.annotation.Configuration; 21 | import org.wso2.carbon.config.annotation.Element; 22 | 23 | import java.util.Locale; 24 | 25 | /** 26 | * Child configuration of the {@link ParentConfiguration}. 27 | * 28 | * since 1.0.0 29 | */ 30 | @Configuration(description = "Child configuration") 31 | public class ChildConfiguration { 32 | 33 | @Element(description = "A boolean field") 34 | private boolean isEnabled = false; 35 | 36 | @Element(description = "A string field") 37 | private String destination = "destination-name"; 38 | 39 | public boolean isEnabled() { 40 | return isEnabled; 41 | } 42 | 43 | public String getDestination() { 44 | return destination; 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | return String.format(Locale.ENGLISH, "destination : %s, isEnabled : %s", 50 | destination, isEnabled); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/complexnamespaceconfig.yaml: -------------------------------------------------------------------------------- 1 | wso2.test.config: 2 | tenant: tenant 3 | transports: 4 | transport: #Transport with direct values 5 | - name: abc 6 | port: 8000 7 | secure: false 8 | desc: This transport will use 8000 as its port 9 | password: ${sec:conn.auth.password} 10 | - name: pqr 11 | port: ${env:pqr.http.port} 12 | secure: ${sys:pqr.secure} 13 | desc: This transport will use ${env:pqr.http.port} as its port. Secure - ${sys:pqr.secure} 14 | - name: xyz 15 | port: ${env:xyz.http.port,9000} 16 | secure: ${sys:xyz.secure,true} 17 | desc: This transport will use ${env:xyz.http.port,8888} as its port 18 | 19 | # TESTCONFIGURATION_TENANT="tenant" 20 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_NAME="abc" 21 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_PORT="8000" 22 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_SECURE="false" 23 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_DESC="This transport will use 8000 as its port" 24 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_PASSWORD="${sec:conn.auth.password}" 25 | 26 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_NAME="pqr" 27 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_PORT="${env:pqr.http.port}" 28 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_SECURE="${sys:pqr.secure}" 29 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_DESC="This transport will use ${env:pqr.http.port} as its port. Secure - ${sys:pqr.secure}" 30 | 31 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_NAME="xyz" 32 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_PORT="${env:xyz.http.port,9000}" 33 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_SECURE="${sys:xyz.secure,true}" 34 | # TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_DESC="This transport will use ${env:xyz.http.port,8888} as its port" -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/java/org/wso2/carbon/config/configprovider/ComplexNameSpaceConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | * 18 | */ 19 | package org.wso2.carbon.config.configprovider; 20 | 21 | import org.wso2.carbon.config.annotation.Configuration; 22 | 23 | import javax.xml.bind.annotation.XmlElement; 24 | import javax.xml.bind.annotation.XmlRootElement; 25 | 26 | /** 27 | * Sample configuration class for testing purposes. 28 | * 29 | * @since 1.0.0 30 | */ 31 | @XmlRootElement(name = "testconfiguration") 32 | @Configuration(namespace = "wso2.test.config", description = "Test Configurations Bean") 33 | public class ComplexNameSpaceConfiguration { 34 | 35 | private String tenant = "default"; 36 | private Transports transports = new Transports(); 37 | 38 | @XmlElement 39 | public void setTenant(String tenant) { 40 | this.tenant = tenant; 41 | } 42 | 43 | public String getTenant() { 44 | return tenant; 45 | } 46 | 47 | @XmlElement 48 | public void setTransports(Transports transports) { 49 | this.transports = transports; 50 | } 51 | 52 | public Transports getTransports() { 53 | return transports; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/org.wso2.carbon.config.test/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | carbon-config 20 | org.wso2.carbon.config 21 | 2.1.18-SNAPSHOT 22 | ../../pom.xml 23 | 24 | 4.0.0 25 | org.wso2.carbon.config.test 26 | Carbon Configuration Tests 27 | jar 28 | http://wso2.com 29 | 30 | 31 | org.testng 32 | testng 33 | 34 | 35 | org.wso2.carbon.config 36 | org.wso2.carbon.config 37 | 38 | 39 | commons-io.wso2 40 | commons-io 41 | test 42 | 43 | 44 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/java/org/wso2/carbon/config/ConfigConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config; 17 | 18 | /** 19 | * Configuration Constants. 20 | * 21 | * @since 1.0.0 22 | */ 23 | public final class ConfigConstants { 24 | 25 | public static final String NULL = "NULL"; 26 | public static final String TEMP_CONFIG_FILE_NAME = "temp_config_classnames.txt"; 27 | public static final String CONFIG_DIR = "config-docs"; 28 | public static final String DEPLOYMENT_CONFIG_YAML = "deployment.yaml"; 29 | public static final String SYSTEM_PROPERTY_DOC_GENERATION = "config.doc.generation"; 30 | public static final String CURRENT_DIRECTORY = "currentDirectory"; 31 | 32 | /** 33 | * Maven project properties. 34 | */ 35 | public static final String PROJECT_DEFAULTS_PROPERTY_FILE = "project.defaults.properties"; 36 | 37 | /** 38 | * Default value if it is not set in sys prop/env. 39 | */ 40 | public static class PlaceHolders { 41 | public static final String SERVER_KEY = "carbon-kernel"; 42 | public static final String SERVER_NAME = "WSO2 Carbon Kernel"; 43 | public static final String SERVER_VERSION = "5"; 44 | 45 | private PlaceHolders() { 46 | } 47 | } 48 | 49 | private ConfigConstants() { 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /samples/config-generator/src/main/java/org/wso2/carbon/config/samples/ChildConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.carbon.config.samples; 19 | 20 | import org.wso2.carbon.config.annotation.Configuration; 21 | import org.wso2.carbon.config.annotation.Element; 22 | 23 | import java.util.Locale; 24 | 25 | /** 26 | * Child configuration of the {@link ParentConfiguration}. 27 | * Don't need to specify the namespace in child configuration class, since the configuration is a part of the 28 | * ParentConfiguration. 29 | * Specifying the namespace will break this configuration to a separate configuration segment under specified namespace 30 | * 31 | * since 1.0.0 32 | */ 33 | @Configuration(description = "Child configuration") 34 | public class ChildConfiguration { 35 | 36 | @Element(description = "A boolean field") 37 | private boolean isEnabled = false; 38 | 39 | @Element(description = "A string field") 40 | private String destination = "destination-name"; 41 | 42 | public boolean isEnabled() { 43 | return isEnabled; 44 | } 45 | 46 | public String getDestination() { 47 | return destination; 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return String.format(Locale.ENGLISH, "destination : %s, isEnabled : %s", 53 | destination, isEnabled); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/java/org/wso2/carbon/config/configprovider/TestUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.carbon.config.configprovider; 19 | 20 | 21 | import java.net.URL; 22 | import java.nio.file.Path; 23 | import java.nio.file.Paths; 24 | import java.util.Optional; 25 | 26 | /** 27 | * Class containing common methods required for testing. 28 | * 29 | * @since 2.0.0 30 | */ 31 | public class TestUtils { 32 | private static final String OS_NAME_KEY = "os.name"; 33 | private static final String WINDOWS_PARAM = "indow"; 34 | 35 | /** 36 | * Get the path of a provided resource. 37 | * 38 | * @param resourcePaths path strings to the location of the resource 39 | * @return path of the resources 40 | */ 41 | public static Optional getResourcePath(String... resourcePaths) { 42 | URL resourceURL = TestUtils.class.getClassLoader().getResource(""); 43 | if (resourceURL != null) { 44 | String resourcePath = resourceURL.getPath(); 45 | if (resourcePath != null) { 46 | resourcePath = System.getProperty(OS_NAME_KEY).contains(WINDOWS_PARAM) ? 47 | resourcePath.substring(1) : resourcePath; 48 | return Optional.ofNullable(Paths.get(resourcePath, resourcePaths)); 49 | } 50 | } 51 | return Optional.empty(); // Resource do not exist 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /samples/config-provider/osgi-bundle/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | carbon-config 20 | org.wso2.carbon.config 21 | 2.1.18-SNAPSHOT 22 | ../../../pom.xml 23 | 24 | 4.0.0 25 | provider-bundle 26 | Carbon Configuration OSGi Sample 27 | bundle 28 | http://wso2.com 29 | 30 | 31 | org.wso2.carbon.config 32 | org.wso2.carbon.config 33 | 34 | 35 | org.slf4j 36 | slf4j-api 37 | 38 | 39 | 40 | 41 | org.wso2.carbon.config.samples.bundle.*;version="${carbon.config.version}" 42 | 43 | 44 | org.wso2.carbon.config.*;version="${carbon.config.package.import.version.range}", 45 | org.slf4j.*;version="${slf4j.logging.package.import.version.range}", 46 | org.osgi.framework.*;version="${osgi.framework.package.import.version.range}" 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /samples/config-generator/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | carbon-config 20 | org.wso2.carbon.config 21 | 2.1.18-SNAPSHOT 22 | ../../pom.xml 23 | 24 | 4.0.0 25 | config-generator 26 | Carbon Configuration Document Generation Sample 27 | jar 28 | http://wso2.com 29 | 30 | 31 | org.wso2.carbon.config 32 | org.wso2.carbon.config 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | org.wso2.carbon.config 41 | org.wso2.carbon.config.maven.plugin 42 | ${carbon.config.version} 43 | 44 | 45 | 46 | create-doc 47 | 48 | compile 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /samples/config-generator/src/main/java/org/wso2/carbon/config/samples/ParentConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.carbon.config.samples; 19 | 20 | import org.wso2.carbon.config.annotation.Configuration; 21 | import org.wso2.carbon.config.annotation.Element; 22 | import org.wso2.carbon.config.annotation.Ignore; 23 | 24 | import java.util.Locale; 25 | 26 | /** 27 | * Parent configuration class. 28 | * 29 | * @since 1.0.0 30 | */ 31 | @Configuration(namespace = "wso2.configuration", description = "Parent configuration") 32 | public class ParentConfiguration { 33 | 34 | @Element(description = "An example element for this configuration") 35 | private String name = "WSO2"; 36 | 37 | @Element(description = "Another example element in the config", required = true) 38 | private int value = 10; 39 | 40 | // This value will not be visible in the configuration 41 | @Ignore 42 | private String ignored = "Ignored String"; 43 | 44 | @Element(description = "Second level configuration") 45 | private ChildConfiguration childConfiguration = new ChildConfiguration(); 46 | 47 | public String getName() { 48 | return name; 49 | } 50 | 51 | public int getValue() { 52 | return value; 53 | } 54 | 55 | public String getIgnored() { 56 | return ignored; 57 | } 58 | 59 | public ChildConfiguration getChildConfiguration() { 60 | return childConfiguration; 61 | } 62 | 63 | @Override 64 | public String toString() { 65 | return String.format(Locale.ENGLISH, "name : %s, value : %s, childConfiguration - %s", 66 | name, value, childConfiguration); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /samples/config-provider/osgi-bundle/src/main/java/org/wso2/carbon/config/samples/bundle/ParentConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.carbon.config.samples.bundle; 19 | 20 | import org.wso2.carbon.config.annotation.Configuration; 21 | import org.wso2.carbon.config.annotation.Element; 22 | import org.wso2.carbon.config.annotation.Ignore; 23 | 24 | import java.util.Locale; 25 | 26 | /** 27 | * Parent configuration class. 28 | * 29 | * @since 1.0.0 30 | */ 31 | @Configuration(namespace = "wso2.configuration", description = "Parent configuration") 32 | public class ParentConfiguration { 33 | 34 | @Element(description = "An example element for this configuration") 35 | private String name = "WSO2"; 36 | 37 | @Element(description = "Another example element in the config", required = true) 38 | private int value = 10; 39 | 40 | // This value will not be visible in the configuration 41 | @Ignore 42 | private String ignored = "Ignored String"; 43 | 44 | @Element(description = "Second level configuration") 45 | private ChildConfiguration childConfiguration = new ChildConfiguration(); 46 | 47 | public String getName() { 48 | return name; 49 | } 50 | 51 | public int getValue() { 52 | return value; 53 | } 54 | 55 | public String getIgnored() { 56 | return ignored; 57 | } 58 | 59 | public ChildConfiguration getChildConfiguration() { 60 | return childConfiguration; 61 | } 62 | 63 | @Override 64 | public String toString() { 65 | return String.format(Locale.ENGLISH, "name : %s, value : %s, childConfiguration - %s", 66 | name, value, childConfiguration); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Purpose 2 | > Describe the problems, issues, or needs driving this feature/fix and include links to related issues in the following format: Resolves issue1, issue2, etc. 3 | 4 | ## Goals 5 | > Describe the solutions that this feature/fix will introduce to resolve the problems described above 6 | 7 | ## Approach 8 | > Describe how you are implementing the solutions. Include an animated GIF or screenshot if the change affects the UI (email documentation@wso2.com to review all UI text). Include a link to a Markdown file or Google doc if the feature write-up is too long to paste here. 9 | 10 | ## User stories 11 | > Summary of user stories addressed by this change> 12 | 13 | ## Release note 14 | > Brief description of the new feature or bug fix as it will appear in the release notes 15 | 16 | ## Documentation 17 | > Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter “N/A” plus brief explanation of why there’s no doc impact 18 | 19 | ## Training 20 | > Link to the PR for changes to the training content in https://github.com/wso2/WSO2-Training, if applicable 21 | 22 | ## Certification 23 | > Type “Sent” when you have provided new/updated certification questions, plus four answers for each question (correct answer highlighted in bold), based on this change. Certification questions/answers should be sent to certification@wso2.com and NOT pasted in this PR. If there is no impact on certification exams, type “N/A” and explain why. 24 | 25 | ## Marketing 26 | > Link to drafts of marketing content that will describe and promote this feature, including product page changes, technical articles, blog posts, videos, etc., if applicable 27 | 28 | ## Automation tests 29 | - Unit tests 30 | > Code coverage information 31 | - Integration tests 32 | > Details about the test cases and coverage 33 | 34 | ## Security checks 35 | - Followed secure coding standards in http://wso2.com/technical-reports/wso2-secure-engineering-guidelines? yes/no 36 | - Ran FindSecurityBugs plugin and verified report? yes/no 37 | - Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets? yes/no 38 | 39 | ## Samples 40 | > Provide high-level details about the samples related to this feature 41 | 42 | ## Related PRs 43 | > List any other related PRs 44 | 45 | ## Migrations (if applicable) 46 | > Describe migration steps and platforms on which migration has been tested 47 | 48 | ## Test environment 49 | > List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested 50 | 51 | ## Learning 52 | > Describe the research phase and any blog posts, patterns, libraries, or add-ons you used to solve the problem. -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/resources/conf/sampledatasource.yaml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the \"License\"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an \"AS IS\" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ################################################################################ 16 | 17 | # Data Sources Configuration 18 | wso2.datasources: 19 | - name: WSO2_CARBON_DB 20 | description: The datasource used for registry and user manager 21 | # JNDI mapping of a data source 22 | jndiConfig: 23 | # JNDI name 24 | # THIS IS A MANDATORY FIELD 25 | name: jdbc/WSO2CarbonDB/test 26 | # JNDI Reference Flag 27 | useJndiReference: true 28 | # data source definition 29 | definition: 30 | # data source type 31 | # THIS IS A MANDATORY FIELD 32 | type: RDBMS 33 | # data source configuration 34 | configuration: 35 | jdbcUrl: 'jdbc:h2:./target/database/TEST_DB1;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=60000' 36 | username: wso2carbon 37 | password: wso2carbon 38 | driverClassName: org.h2.Driver 39 | maxPoolSize: 50 40 | idleTimeout: 60000 41 | connectionTestQuery: SELECT 1 42 | validationTimeout: 30000 43 | isAutoCommit: false 44 | - name: WSO2_ANALYTICS_DB 45 | description: The datasource used for registry and user manager 46 | # JNDI mapping of a data source 47 | jndiConfig: 48 | # JNDI name 49 | # THIS IS A MANDATORY FIELD 50 | name: jdbc/WSO2CarbonDB/testDb2 51 | # JNDI Reference Flag 52 | useJndiReference: true 53 | definition: 54 | # data source type 55 | # THIS IS A MANDATORY FIELD 56 | type: RDBMS 57 | # data source configuration 58 | configuration: 59 | jdbcUrl: 'jdbc:h2:./target/database/ANALYTICS_DB1;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=60000' 60 | username: wso2carbon 61 | password: wso2carbon 62 | driverClassName: org.h2.Driver 63 | maxPoolSize: 50 64 | idleTimeout: 60000 65 | connectionTestQuery: SELECT 1 66 | validationTimeout: 30000 67 | isAutoCommit: false 68 | 69 | -------------------------------------------------------------------------------- /samples/config-provider/osgi-bundle/src/main/java/org/wso2/carbon/config/samples/bundle/internal/ConfigurationServiceComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.carbon.config.samples.bundle.internal; 19 | 20 | import org.osgi.service.component.annotations.Activate; 21 | import org.osgi.service.component.annotations.Component; 22 | import org.osgi.service.component.annotations.Reference; 23 | import org.osgi.service.component.annotations.ReferenceCardinality; 24 | import org.osgi.service.component.annotations.ReferencePolicy; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | import org.wso2.carbon.config.ConfigurationException; 28 | import org.wso2.carbon.config.provider.ConfigProvider; 29 | import org.wso2.carbon.config.samples.bundle.ParentConfiguration; 30 | 31 | /** 32 | * Declarative service component used with the example configuration bundle. 33 | */ 34 | @Component( 35 | name = "org.wso2.carbon.config.samples.bundle.internal.ConfigurationServiceComponent", 36 | immediate = true 37 | ) 38 | public class ConfigurationServiceComponent { 39 | 40 | private static final Logger logger = LoggerFactory 41 | .getLogger(ConfigurationServiceComponent.class); 42 | private ConfigProvider configProvider; 43 | 44 | @Activate 45 | public void start() throws ConfigurationException { 46 | ParentConfiguration parentConfiguration = configProvider 47 | .getConfigurationObject(ParentConfiguration.class); 48 | logger.info("Parent configuration - {}", parentConfiguration); 49 | } 50 | 51 | @Reference( 52 | name = "carbon.config.provider", 53 | service = ConfigProvider.class, 54 | cardinality = ReferenceCardinality.MANDATORY, 55 | policy = ReferencePolicy.DYNAMIC, 56 | unbind = "unregisterConfigProvider" 57 | ) 58 | protected void registerConfigProvider(ConfigProvider configProvider) { 59 | this.configProvider = configProvider; 60 | } 61 | 62 | protected void unregisterConfigProvider(ConfigProvider configProvider) { 63 | this.configProvider = null; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/java/org/wso2/carbon/config/configprovider/BasicTestConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.config.configprovider; 20 | 21 | import org.wso2.carbon.config.annotation.Configuration; 22 | 23 | import javax.xml.bind.annotation.XmlElement; 24 | import javax.xml.bind.annotation.XmlRootElement; 25 | 26 | /** 27 | * Sample configuration class for testing purposes. 28 | * 29 | * @since 2.0.6 30 | */ 31 | @XmlRootElement 32 | @Configuration(description = "Test Bean") 33 | class TestBean { 34 | 35 | private String name = "default"; 36 | 37 | public String getName() { 38 | return name; 39 | } 40 | 41 | @XmlElement 42 | public void setName(String name) { 43 | this.name = name; 44 | } 45 | } 46 | 47 | /** 48 | * Sample configuration class for testing purposes. 49 | * 50 | * @since 2.0.6 51 | */ 52 | @XmlRootElement 53 | @Configuration(description = "Complex Test Bean") 54 | class ComplexTestBean { 55 | 56 | private String name = "default"; 57 | private TestBean testBean = new TestBean(); 58 | 59 | public String getName() { 60 | return name; 61 | } 62 | 63 | @XmlElement 64 | public void setName(String name) { 65 | this.name = name; 66 | } 67 | 68 | public TestBean getTestBean() { 69 | return testBean; 70 | } 71 | 72 | @XmlElement 73 | public void setTestBean(TestBean testBean) { 74 | this.testBean = testBean; 75 | } 76 | } 77 | 78 | /** 79 | * Sample configuration class for testing purposes. 80 | * 81 | * @since 2.0.6 82 | */ 83 | @XmlRootElement(name = "basictestconfiguration") 84 | @Configuration(namespace = "basictestconfiguration", description = "Test Configurations Bean") 85 | public class BasicTestConfiguration { 86 | 87 | private TestBean testBean = new TestBean(); 88 | private ComplexTestBean complexTestBean = new ComplexTestBean(); 89 | 90 | public TestBean getTestBean() { 91 | return testBean; 92 | } 93 | 94 | @XmlElement 95 | public void setTestBean(TestBean testBean) { 96 | this.testBean = testBean; 97 | } 98 | 99 | public ComplexTestBean getComplexTestBean() { 100 | return complexTestBean; 101 | } 102 | 103 | @XmlElement 104 | public void setComplexTestBean(ComplexTestBean complexTestBean) { 105 | this.complexTestBean = complexTestBean; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/java/org/wso2/carbon/config/configprovider/PriorityTestConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config.configprovider; 17 | 18 | import org.wso2.carbon.config.annotation.Configuration; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | import javax.xml.bind.annotation.XmlElement; 23 | import javax.xml.bind.annotation.XmlRootElement; 24 | 25 | /** 26 | * Sample configuration class for testing purposes. 27 | * 28 | * @since 2.0.6 29 | */ 30 | @XmlRootElement 31 | @Configuration(description = "Priority Test Bean") 32 | class PriorityTestBean { 33 | 34 | private String name = "default"; 35 | private int id = 0; 36 | private int port = 8000; 37 | 38 | public int getId() { 39 | return id; 40 | } 41 | 42 | @XmlElement 43 | public void setId(int id) { 44 | this.id = id; 45 | } 46 | 47 | public String getName() { 48 | return name; 49 | } 50 | 51 | @XmlElement 52 | public void setName(String name) { 53 | this.name = name; 54 | } 55 | 56 | public int getPort() { 57 | return port; 58 | } 59 | 60 | @XmlElement 61 | public void setPort(int port) { 62 | this.port = port; 63 | } 64 | } 65 | 66 | /** 67 | * Sample configuration class for testing purposes. 68 | * 69 | * @since 2.0.6 70 | */ 71 | @XmlRootElement 72 | @Configuration(description = "Test Beans") 73 | class TestBeans { 74 | 75 | private List testBeanList; 76 | 77 | TestBeans() { 78 | testBeanList = new ArrayList<>(); 79 | testBeanList.add(new PriorityTestBean()); 80 | } 81 | 82 | public List getTestBeanList() { 83 | return testBeanList; 84 | } 85 | 86 | @XmlElement 87 | public void setTestBeanList(List testBeans) { 88 | this.testBeanList = testBeans; 89 | } 90 | 91 | } 92 | 93 | /** 94 | * Sample configuration class for testing purposes. 95 | * 96 | * @since 2.0.6 97 | */ 98 | @XmlRootElement(name = "prioritytestconfiguration") 99 | @Configuration(namespace = "prioritytestconfiguration", description = "Priority Test Configurations Bean") 100 | public class PriorityTestConfiguration { 101 | 102 | private TestBeans testBeans = new TestBeans(); 103 | 104 | public TestBeans getTestBeans() { 105 | return testBeans; 106 | } 107 | 108 | @XmlElement 109 | public void setTestBeans(TestBeans priorityTestBeans) { 110 | this.testBeans = priorityTestBeans; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/java/org/wso2/carbon/config/configprovider/UniqueElementTestConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config.configprovider; 17 | 18 | import org.wso2.carbon.config.annotation.Configuration; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | import javax.xml.bind.annotation.XmlElement; 23 | import javax.xml.bind.annotation.XmlRootElement; 24 | 25 | /** 26 | * Sample configuration class for testing purposes. 27 | * 28 | * @since 2.0.6 29 | */ 30 | @XmlRootElement 31 | @Configuration(description = "Unique Element Test Bean") 32 | class UniqueElementTestBean { 33 | 34 | private String uniqueElement = "default"; 35 | private int port = 8000; 36 | 37 | public String getUniqueElement() { 38 | return uniqueElement; 39 | } 40 | 41 | @XmlElement 42 | public void setUniqueElement(String uniqueElement) { 43 | this.uniqueElement = uniqueElement; 44 | } 45 | 46 | public int getPort() { 47 | return port; 48 | } 49 | 50 | @XmlElement 51 | public void setPort(int port) { 52 | this.port = port; 53 | } 54 | } 55 | 56 | /** 57 | * Sample configuration class for testing purposes. 58 | * 59 | * @since 2.0.6 60 | */ 61 | @XmlRootElement 62 | @Configuration(description = "Unique Element Test Beans") 63 | class UniqueElementTestBeans { 64 | 65 | private List uniqueElementTestBeanList; 66 | 67 | UniqueElementTestBeans() { 68 | uniqueElementTestBeanList = new ArrayList<>(); 69 | uniqueElementTestBeanList.add(new UniqueElementTestBean()); 70 | } 71 | 72 | public List getUniqueElementTestBeanList() { 73 | return uniqueElementTestBeanList; 74 | } 75 | 76 | @XmlElement 77 | public void setUniqueElementTestBeanList(List uniqueElementTestBeanList) { 78 | this.uniqueElementTestBeanList = uniqueElementTestBeanList; 79 | } 80 | 81 | } 82 | 83 | /** 84 | * Sample configuration class for testing purposes. 85 | * 86 | * @since 2.0.6 87 | */ 88 | @XmlRootElement(name = "uniqueelementtestconfiguration") 89 | @Configuration(namespace = "uniqueelementtestconfiguration", description = "Unique Element Test Configurations Bean") 90 | public class UniqueElementTestConfiguration { 91 | 92 | private UniqueElementTestBeans uniqueElementTestBeans = new UniqueElementTestBeans(); 93 | 94 | public UniqueElementTestBeans getUniqueElementTestBeans() { 95 | return uniqueElementTestBeans; 96 | } 97 | 98 | @XmlElement 99 | public void setUniqueElementTestBeans(UniqueElementTestBeans uniqueElementTestBeans) { 100 | this.uniqueElementTestBeans = uniqueElementTestBeans; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /features/org.wso2.carbon.config.feature/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | carbon-config 20 | org.wso2.carbon.config 21 | 2.1.18-SNAPSHOT 22 | ../../pom.xml 23 | 24 | 4.0.0 25 | carbon-feature 26 | org.wso2.carbon.config.feature 27 | Carbon Configuration Feature 28 | http://wso2.com 29 | 30 | 31 | org.wso2.carbon.config 32 | org.wso2.carbon.config 33 | 34 | 35 | 36 | 37 | 38 | org.wso2.carbon.maven 39 | carbon-feature-plugin 40 | true 41 | 42 | 43 | p2-feature-generation 44 | package 45 | 46 | generate 47 | 48 | 49 | ../etc/feature.properties 50 | 51 | 52 | org.eclipse.equinox.p2.type.group 53 | false 54 | 55 | 56 | 57 | 58 | org.wso2.carbon.config 59 | ${carbon.config.version} 60 | 61 | 62 | 63 | 64 | org.wso2.carbon.secvault.feature 65 | ${carbon.securevault.version} 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /extensions/org.wso2.carbon.config.maven.plugin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | org.wso2.carbon.config 20 | carbon-config 21 | 2.1.18-SNAPSHOT 22 | ../../pom.xml 23 | 24 | 4.0.0 25 | org.wso2.carbon.config.maven.plugin 26 | maven-plugin 27 | Carbon Configuration Maven Plugin 28 | 29 | This module has mojo class for carbon configuration plugin. 30 | 31 | http://wso2.com 32 | 33 | 34 | org.apache.maven 35 | maven-project 36 | 37 | 38 | org.apache.maven 39 | maven-plugin-api 40 | 41 | 42 | org.apache.maven.plugin-tools 43 | maven-plugin-annotations 44 | 45 | 46 | org.apache.maven 47 | maven-core 48 | 49 | 50 | org.slf4j 51 | slf4j-api 52 | 53 | 54 | org.yaml 55 | snakeyaml 56 | 57 | 58 | org.wso2.carbon.config 59 | org.wso2.carbon.config 60 | 61 | 62 | 63 | 64 | 65 | org.apache.maven.plugins 66 | maven-plugin-plugin 67 | ${maven.plugin.plugin.version} 68 | 69 | true 70 | 71 | 72 | 73 | mojo-descriptor 74 | process-classes 75 | 76 | descriptor 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/java/org/wso2/carbon/config/provider/ConfigProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.carbon.config.provider; 19 | 20 | import org.wso2.carbon.config.ConfigurationException; 21 | 22 | import java.util.ArrayList; 23 | 24 | /** 25 | * ConfigProvider provides the configuration mapping of the class namespace. 26 | * This will update the configuration values with 27 | * following placeholders ${env:alias}, ${sys:alias} and ${sec:alias} 28 | * 29 | * @since 1.0.0 30 | */ 31 | public interface ConfigProvider { 32 | 33 | /** 34 | * Returns configuration object of the class. 35 | * if configuration doesn't exist in deployment.yaml, returns object with default values. 36 | * 37 | * @param configClass configuration bean class 38 | * @param object type 39 | * @return configuration bean object of given type 40 | * @throws ConfigurationException if there is a problem with config object instantiation. 41 | */ 42 | T getConfigurationObject(Class configClass) throws ConfigurationException; 43 | 44 | /** 45 | * Returns configuration object of the namespace. 46 | * Configuration object can be either List or Map, it depends on configuration of the namespace. 47 | * 48 | * @param namespace config namespace 49 | * @return configuration object 50 | * @throws ConfigurationException if there is a problem while reading the configurations 51 | */ 52 | Object getConfigurationObject(String namespace) throws ConfigurationException; 53 | 54 | /** 55 | * Returns configuration object of the class. 56 | *

57 | * If configuration namespace is given, reads the configuration of the namespace and create instance of the the 58 | * class from that configurations. 59 | *

60 | * If namespace is null or configuration doesn't exist for in configuration file, returns configurations based on 61 | * the bean class. 62 | * 63 | * @param namespace config namespace 64 | * @param configClass configuration bean class 65 | * @param object type 66 | * @return configuration object 67 | * @throws ConfigurationException if there is a problem while reading the configurations 68 | */ 69 | T getConfigurationObject(String namespace, Class configClass) throws ConfigurationException; 70 | 71 | /** 72 | * Returns te configuration object list of the class under the namespace 73 | * 74 | * @param namespace config namespace 75 | * @param configClass configuration bean class 76 | * @param object type 77 | * @return list of configuration object 78 | * @throws ConfigurationException if there is a problem while reading the configurations 79 | */ 80 | ArrayList getConfigurationObjectList(String namespace, Class configClass) throws ConfigurationException; 81 | } 82 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/java/org/wso2/carbon/config/ConfigurationProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config; 17 | 18 | import org.wso2.carbon.config.annotation.Configuration; 19 | 20 | import java.io.IOException; 21 | import java.io.Writer; 22 | import java.util.Set; 23 | import javax.annotation.processing.AbstractProcessor; 24 | import javax.annotation.processing.RoundEnvironment; 25 | import javax.annotation.processing.SupportedAnnotationTypes; 26 | import javax.annotation.processing.SupportedSourceVersion; 27 | import javax.lang.model.SourceVersion; 28 | import javax.lang.model.element.Element; 29 | import javax.lang.model.element.TypeElement; 30 | import javax.tools.Diagnostic; 31 | import javax.tools.FileObject; 32 | import javax.tools.StandardLocation; 33 | 34 | /** 35 | * Configuration annotation processor extending AbstractProcessor. 36 | * Reads all classes annotated Configuration 37 | * 38 | * @since 1.0.0 39 | */ 40 | @SupportedAnnotationTypes("org.wso2.carbon.config.annotation.Configuration") 41 | @SupportedSourceVersion(SourceVersion.RELEASE_8) 42 | public class ConfigurationProcessor extends AbstractProcessor { 43 | 44 | public ConfigurationProcessor() { 45 | super(); 46 | } 47 | 48 | /** 49 | * This method reads all Configuration classes in the project and create temp files with qualified names of classes. 50 | * 51 | * @param annotations set of annotations 52 | * @param roundEnv annotation object to process 53 | * @return return true if processing is completed, false otherwise 54 | */ 55 | @Override 56 | public boolean process(Set annotations, RoundEnvironment roundEnv) { 57 | Set configSet = roundEnv.getElementsAnnotatedWith(Configuration.class); 58 | StringBuilder builder = new StringBuilder(); 59 | for (Element element : configSet) { 60 | Configuration configuration = element.getAnnotation(Configuration.class); 61 | if (configuration != null && !ConfigConstants.NULL.equals(configuration.namespace())) { 62 | builder.append(((TypeElement) element).getQualifiedName()).append(","); 63 | } 64 | } 65 | if (builder.length() > 0) { 66 | try { 67 | FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", 68 | ConfigConstants.TEMP_CONFIG_FILE_NAME); 69 | try (Writer writer = file.openWriter()) { 70 | writer.write(builder.toString()); 71 | } 72 | } catch (IOException e) { 73 | processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); 74 | } 75 | } else { 76 | processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Configuration classes doesn't exist in " + 77 | "the project"); 78 | } 79 | return true; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/java/org/wso2/carbon/config/configprovider/TestTransportConfiguration2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config.configprovider; 17 | 18 | import org.wso2.carbon.config.annotation.Configuration; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | import javax.xml.bind.annotation.XmlAttribute; 23 | import javax.xml.bind.annotation.XmlElement; 24 | import javax.xml.bind.annotation.XmlRootElement; 25 | 26 | /** 27 | * Sample configuration class for testing purposes. 28 | * 29 | * @since 1.0.0 30 | */ 31 | @XmlRootElement 32 | @Configuration(namespace = "testTransports", description = "Test Transports Bean") 33 | class TestTransportRoot { 34 | 35 | public List testTransports; 36 | 37 | TestTransportRoot() { 38 | testTransports = new ArrayList<>(); 39 | testTransports.add(new TestTransportElement()); 40 | } 41 | 42 | @XmlElement 43 | public void setTestTransports(List transportsTest) { 44 | this.testTransports = transportsTest; 45 | } 46 | 47 | public List getTestTransports() { 48 | return testTransports; 49 | } 50 | } 51 | 52 | @XmlRootElement 53 | @Configuration(description = "Test Transport Bean") 54 | class TestTransportElement { 55 | 56 | public TestTransport testTransport = new TestTransport(); 57 | 58 | public TestTransport getTestTransport() { 59 | return testTransport; 60 | } 61 | 62 | public void setTestTransport(TestTransport testTransport) { 63 | this.testTransport = testTransport; 64 | } 65 | } 66 | 67 | @XmlRootElement 68 | @Configuration(description = "Test Transport Bean") 69 | class TestTransport { 70 | 71 | public String name = "default transport"; 72 | public int port = 8000; 73 | public boolean secure = false; 74 | public String desc = "Default Transport Configurations"; 75 | public String password = "zzz"; 76 | 77 | @XmlAttribute 78 | public void setSecure(boolean secure) { 79 | this.secure = secure; 80 | } 81 | 82 | public boolean isSecure() { 83 | return secure; 84 | } 85 | 86 | @XmlElement 87 | public void setName(String name) { 88 | this.name = name; 89 | } 90 | 91 | public String getName() { 92 | return name; 93 | } 94 | 95 | @XmlElement 96 | public void setPort(int port) { 97 | this.port = port; 98 | } 99 | 100 | public int getPort() { 101 | return port; 102 | } 103 | 104 | @XmlElement 105 | public void setDesc(String desc) { 106 | this.desc = desc; 107 | } 108 | 109 | public String getDesc() { 110 | return desc; 111 | } 112 | 113 | @XmlElement 114 | public void setPassword(String password) { 115 | this.password = password; 116 | } 117 | 118 | public String getPassword() { 119 | return password; 120 | } 121 | } 122 | 123 | -------------------------------------------------------------------------------- /samples/config-provider/standalone/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | carbon-config 20 | org.wso2.carbon.config 21 | 2.1.18-SNAPSHOT 22 | ../../../pom.xml 23 | 24 | 4.0.0 25 | provider-standalone 26 | Carbon Configuration Standalone Sample 27 | jar 28 | http://wso2.com 29 | 30 | 31 | org.wso2.carbon.config 32 | org.wso2.carbon.config 33 | 34 | 35 | org.slf4j 36 | slf4j-api 37 | 38 | 39 | org.slf4j 40 | slf4j-log4j12 41 | ${slf4j.api.version} 42 | 43 | 44 | org.wso2.carbon.config 45 | config-generator 46 | ${project.version} 47 | 48 | 49 | 50 | 51 | 52 | org.apache.maven.plugins 53 | maven-assembly-plugin 54 | 55 | 56 | jar-with-dependencies 57 | package 58 | 59 | single 60 | 61 | 62 | 63 | 64 | 65 | org.wso2.carbon.config.samples.standalone.Application 66 | 67 | 68 | 69 | false 70 | false 71 | 72 | assembly.xml 73 | 74 | 75 | provider-standalone-${project.version} 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 1.7.13 86 | 87 | 88 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/java/org/wso2/carbon/config/internal/ConfigProviderComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.carbon.config.internal; 19 | 20 | import org.osgi.framework.BundleContext; 21 | import org.osgi.service.component.annotations.Activate; 22 | import org.osgi.service.component.annotations.Component; 23 | import org.osgi.service.component.annotations.Deactivate; 24 | import org.osgi.service.component.annotations.Reference; 25 | import org.osgi.service.component.annotations.ReferenceCardinality; 26 | import org.osgi.service.component.annotations.ReferencePolicy; 27 | import org.slf4j.Logger; 28 | import org.slf4j.LoggerFactory; 29 | import org.wso2.carbon.config.ConfigProviderFactory; 30 | import org.wso2.carbon.config.ConfigurationException; 31 | import org.wso2.carbon.config.provider.ConfigProvider; 32 | import org.wso2.carbon.secvault.SecureVault; 33 | import org.wso2.carbon.utils.Constants; 34 | import org.wso2.carbon.utils.Utils; 35 | 36 | import java.nio.file.Path; 37 | import java.nio.file.Paths; 38 | 39 | /** 40 | * This service component is responsible for registering ConfigProvider OSGi service. 41 | * 42 | * @since 1.0.0 43 | */ 44 | @Component( 45 | name = "ConfigProviderComponent", 46 | immediate = true 47 | ) 48 | public class ConfigProviderComponent { 49 | private static final Logger logger = LoggerFactory.getLogger(ConfigProviderComponent.class); 50 | private SecureVault secureVault = null; 51 | 52 | @Activate 53 | protected void activate(BundleContext bundleContext) { 54 | initializeConfigProvider(bundleContext); 55 | logger.debug("Carbon Configuration Component activated"); 56 | } 57 | 58 | @Deactivate 59 | protected void deactivate(BundleContext bundleContext) { 60 | logger.debug("Stopping ConfigProviderComponent"); 61 | } 62 | 63 | @Reference( 64 | name = "org.wso2.carbon.secvault.SecureVault", 65 | service = SecureVault.class, 66 | cardinality = ReferenceCardinality.MANDATORY, 67 | policy = ReferencePolicy.DYNAMIC, 68 | unbind = "unRegisterSecureVault" 69 | ) 70 | protected void registerSecureVault(SecureVault secureVault) { 71 | this.secureVault = secureVault; 72 | } 73 | 74 | protected void unRegisterSecureVault(SecureVault secureVault) { 75 | this.secureVault = null; 76 | } 77 | 78 | /** 79 | * Initialise carbon config provider. 80 | * 81 | * @param bundleContext OSGi Bundle Context 82 | */ 83 | private void initializeConfigProvider(BundleContext bundleContext) { 84 | try { 85 | Path deploymentConfigPath = Paths.get(Utils.getRuntimeConfigPath().toString(), 86 | Constants.DEPLOYMENT_CONFIG_YAML); 87 | ConfigProvider configProvider = ConfigProviderFactory.getConfigProvider(deploymentConfigPath, secureVault); 88 | bundleContext.registerService(ConfigProvider.class, configProvider, null); 89 | logger.debug("ConfigProvider OSGi service registered successfully"); 90 | } catch (ConfigurationException e) { 91 | logger.error("Error occurred while initializing config provider" , e); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/java/org/wso2/carbon/config/configprovider/TestConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config.configprovider; 17 | 18 | import org.wso2.carbon.config.annotation.Configuration; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | import javax.xml.bind.annotation.XmlAttribute; 23 | import javax.xml.bind.annotation.XmlElement; 24 | import javax.xml.bind.annotation.XmlRootElement; 25 | 26 | /** 27 | * Sample configuration class for testing purposes. 28 | * 29 | * @since 1.0.0 30 | */ 31 | @XmlRootElement 32 | @Configuration(description = "Test Transport Bean") 33 | class Transport { 34 | 35 | private String name = "default transport"; 36 | private int port = 8000; 37 | private String secure = "false"; 38 | private String desc = "Default Transport Configurations"; 39 | private String password = "zzz"; 40 | 41 | @XmlAttribute 42 | public void setSecure(String secure) { 43 | this.secure = secure; 44 | } 45 | 46 | public String isSecure() { 47 | return secure; 48 | } 49 | 50 | @XmlElement 51 | public void setName(String name) { 52 | this.name = name; 53 | } 54 | 55 | public String getName() { 56 | return name; 57 | } 58 | 59 | @XmlElement 60 | public void setPort(int port) { 61 | this.port = port; 62 | } 63 | 64 | public int getPort() { 65 | return port; 66 | } 67 | 68 | @XmlElement 69 | public void setDesc(String desc) { 70 | this.desc = desc; 71 | } 72 | 73 | public String getDesc() { 74 | return desc; 75 | } 76 | 77 | @XmlElement 78 | public void setPassword(String password) { 79 | this.password = password; 80 | } 81 | 82 | public String getPassword() { 83 | return password; 84 | } 85 | } 86 | 87 | /** 88 | * Sample configuration class for testing purposes. 89 | * 90 | * @since 1.0.0 91 | */ 92 | @XmlRootElement 93 | @Configuration(description = "Test Transports Bean") 94 | class Transports { 95 | 96 | private List transport; 97 | 98 | Transports() { 99 | transport = new ArrayList<>(); 100 | transport.add(new Transport()); 101 | } 102 | 103 | @XmlElement 104 | public void setTransport(List transport) { 105 | this.transport = transport; 106 | } 107 | 108 | public List getTransport() { 109 | return transport; 110 | } 111 | 112 | } 113 | 114 | /** 115 | * Sample configuration class for testing purposes. 116 | * 117 | * @since 1.0.0 118 | */ 119 | @XmlRootElement(name = "testconfiguration") 120 | @Configuration(namespace = "testconfiguration", description = "Test Configurations Bean") 121 | public class TestConfiguration { 122 | 123 | private String tenant = "default"; 124 | private Transports transports = new Transports(); 125 | 126 | @XmlElement 127 | public void setTenant(String tenant) { 128 | this.tenant = tenant; 129 | } 130 | 131 | public String getTenant() { 132 | return tenant; 133 | } 134 | 135 | @XmlElement 136 | public void setTransports(Transports transports) { 137 | this.transports = transports; 138 | } 139 | 140 | public Transports getTransports() { 141 | return transports; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /tests/org.wso2.carbon.config.test/src/test/java/org/wso2/carbon/config/test/annotationprocessor/TestConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config.test.annotationprocessor; 17 | 18 | import org.wso2.carbon.config.annotation.Configuration; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | import javax.xml.bind.annotation.XmlAttribute; 23 | import javax.xml.bind.annotation.XmlElement; 24 | import javax.xml.bind.annotation.XmlRootElement; 25 | 26 | /** 27 | * Sample configuration class for testing purposes. 28 | * 29 | * @since 1.0.0 30 | */ 31 | @XmlRootElement 32 | @Configuration(description = "Test Transport Bean") 33 | class Transport { 34 | 35 | private String name = "default transport"; 36 | private int port = 8000; 37 | private String secure = "false"; 38 | private String desc = "Default Transport Configurations"; 39 | private String password = "zzz"; 40 | 41 | @XmlAttribute 42 | public void setSecure(String secure) { 43 | this.secure = secure; 44 | } 45 | 46 | public String isSecure() { 47 | return secure; 48 | } 49 | 50 | @XmlElement 51 | public void setName(String name) { 52 | this.name = name; 53 | } 54 | 55 | public String getName() { 56 | return name; 57 | } 58 | 59 | @XmlElement 60 | public void setPort(int port) { 61 | this.port = port; 62 | } 63 | 64 | public int getPort() { 65 | return port; 66 | } 67 | 68 | @XmlElement 69 | public void setDesc(String desc) { 70 | this.desc = desc; 71 | } 72 | 73 | public String getDesc() { 74 | return desc; 75 | } 76 | 77 | @XmlElement 78 | public void setPassword(String password) { 79 | this.password = password; 80 | } 81 | 82 | public String getPassword() { 83 | return password; 84 | } 85 | } 86 | 87 | /** 88 | * Sample configuration class for testing purposes. 89 | * 90 | * @since 1.0.0 91 | */ 92 | @XmlRootElement 93 | @Configuration(description = "Test Transports Bean") 94 | class Transports { 95 | 96 | private List transport; 97 | 98 | Transports() { 99 | transport = new ArrayList<>(); 100 | transport.add(new Transport()); 101 | } 102 | 103 | @XmlElement 104 | public void setTransport(List transport) { 105 | this.transport = transport; 106 | } 107 | 108 | public List getTransport() { 109 | return transport; 110 | } 111 | 112 | } 113 | 114 | /** 115 | * Sample configuration class for testing purposes. 116 | * 117 | * @since 1.0.0 118 | */ 119 | @XmlRootElement(name = "testconfiguration") 120 | @Configuration(namespace = "testconfiguration", description = "Test Configurations Bean") 121 | public class TestConfiguration { 122 | 123 | private String tenant = "default"; 124 | private Transports transports = new Transports(); 125 | 126 | @XmlElement 127 | public void setTenant(String tenant) { 128 | this.tenant = tenant; 129 | } 130 | 131 | public String getTenant() { 132 | return tenant; 133 | } 134 | 135 | @XmlElement 136 | public void setTransports(Transports transports) { 137 | this.transports = transports; 138 | } 139 | 140 | public Transports getTransports() { 141 | return transports; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Carbon Configuration 2 | 3 | Carbon configuration provides a framework for managing server configurations. With global configuration model, server 4 | will have only one configuration file for all server configurations. So that, 5 | 6 | * Global configuration file (deployment.yaml) includes minimal sets of configurations which need to override very 7 | often by default (e.g: server ports etc). 8 | * All user settable configurations must have default values and they are burnt into compile codes. 9 | * Any default configuration can overridden by adding the particular configuration to the global configuration 10 | file(deployment.yaml). 11 | * Defining all configurations in the configuration file in not required. add only if we need to override the 12 | default value. 13 | * If configurations are not specified in the configuration file, values defined in the bean class will apply by 14 | default. 15 | 16 | In global configuration file (deployment.yaml), 17 | 18 | * Each component will have their own configurations with a unique namespace (e.g: wso2.carbon, wso2.transports.netty etc) and it will be a fragment of deployment.yaml file. Please find the sample file below. 19 | * At runtime, the relevant config bean will be generated by overriding the default values specified in bean class with values mentioned in deployment.yaml file. 20 | 21 | Sample file looks like: 22 | 23 | ```yaml 24 | # Carbon Configuration Parameters 25 | wso2.carbon: 26 | id: carbon-kernel 27 | version: 5.2.0-SNAPSHOT 28 | ports: 29 | offset: 0 30 | ... 31 | 32 | # Netty Transport Configurations 33 | wso2.transports.netty: 34 | listeners: 35 | - id: msf4j-http 36 | host: 127.0.0.1 37 | port: 8080 38 | bossThreadPoolSize: 2 39 | workerThreadPoolSize: 250 40 | parameters: 41 | - name: "executor.workerpool.size" 42 | value: 60 43 | 44 | ... 45 | ``` 46 | 47 | Following annotations are introduced for configuration bean classes. 48 | 49 | * `org.wso2.carbon.config.annotations.Configuration`: This is a class-level annotation, which corresponds to a configuration bean to be used by a component. 50 | * `org.wso2.carbon.config.annotations.Element`: This is a field-level annotation, which corresponds to a field of the class. 51 | * `org.wso2.carbon.config.annotations.Ignore`: This is a field-level annotation, which specifies that the field needs to be ignored when the configuration is generated. 52 | 53 | Sample bean class with above annotations looks like: 54 | 55 | ```java 56 | @Configuration(namespace = "wso2.carbon", description = "Carbon Configuration Parameters") 57 | public class CarbonConfiguration { 58 | 59 | @Element(description = "value to uniquely identify a server", required = true) 60 | private String id = "carbon-kernel"; 61 | 62 | @Element(description = "server name") 63 | private String name = "WSO2 Carbon Kernel"; 64 | 65 | @Element(description = "server version") 66 | private String version = "5.2.0"; 67 | 68 | @Ignore 69 | private String tenant = Constants.DEFAULT_TENANT; 70 | 71 | } 72 | ``` 73 | 74 | The framework provides maven plugin to read all configuration bean classes in the component and create the relevant 75 | segment of the configuration file(for documentation purposes) automatically at compile time. 76 | 77 | The framework provides OSGI service(ConfigProvider) to read configuration from deployment.yaml file. Following apis 78 | are read configuration from the file. 79 | 80 | * `getConfigurationObject(Class configClass)`: Returns configuration object of the class with overriding the values of deployment.yaml. If configuration doesn't exist in deployment.yaml, returns object with default values. 81 | * `getConfigurationMap(String namespace)`: Returns configuration map of the namespace, if configuration exists for the given namespace in deployment.yaml. 82 | 83 | For more information, Please refer document link below. 84 | 85 | * [Using the Global Configuration Model](docs/UpdatingConfigurations.md) 86 | * [Installing Configuration Provider Feature](docs/InstallingConfigFeature.md) 87 | * [Configurations via Environment Variables](docs/ConfigurationsViaEnvironmentVariables.md) -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/java/org/wso2/carbon/config/provider/ImmutablePair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.carbon.config.provider; 19 | 20 | import java.util.Arrays; 21 | import java.util.Locale; 22 | import java.util.Objects; 23 | 24 | /** 25 | * An {@link ImmutablePair} consists of two elements within. The elements once set 26 | * in the ImmutablePair cannot be modified. The class itself is final, so that it 27 | * cannot be subclassed. This is general norm for creating Immutable classes. 28 | * Please note that the {@link ImmutablePair} cannot be modified once set, but the 29 | * objects within them can be, so in general it means that if there are mutable objects 30 | * within the pair then the pair itself is effectively mutable. 31 | *

32 | *

 33 |  *     ImmutablePair tupleStreamPair =
 34 |  *      new ImmutablePair (tuple, identifier);
 35 |  *   ...
 36 |  *   ...
 37 |  *   Tuple t = tupleStreamPair.getFirst();
 38 |  *   TupleInputStreamIdentifier identifier = tupleStreamPair.getSecond();
 39 |  *   ...
 40 |  * 
41 | * 42 | * @param type A 43 | * @param type B 44 | * @since 2.0.6 45 | */ 46 | final class ImmutablePair { 47 | private final A first; 48 | private final B second; 49 | 50 | /** 51 | * Constructs a Immutable Pair. 52 | * 53 | * @param first object in pair 54 | * @param second object in pair 55 | */ 56 | private ImmutablePair(A first, B second) { 57 | this.first = first; 58 | this.second = second; 59 | } 60 | 61 | public static ImmutablePair of(A first, B second) { 62 | return new ImmutablePair<>(first, second); 63 | } 64 | 65 | /** 66 | * Returns first object from pair. 67 | * 68 | * @return first object from pair. 69 | */ 70 | public A getFirst() { 71 | return first; 72 | } 73 | 74 | /** 75 | * Return second object from pair. 76 | * 77 | * @return second object from pair. 78 | */ 79 | public B getSecond() { 80 | return second; 81 | } 82 | 83 | /** 84 | * Returns a string representation of {@link ImmutablePair} object. 85 | * 86 | * @return string representation of this object. 87 | */ 88 | @Override 89 | public String toString() { 90 | return String.format(Locale.ENGLISH, "{ first: %s, second: %s }", first, second); 91 | } 92 | 93 | /** 94 | * Returns a hash code value for this object. 95 | * 96 | * @return hash code value of this object. 97 | */ 98 | @Override 99 | public int hashCode() { 100 | return Arrays.hashCode(new ImmutablePair[]{(ImmutablePair) first, (ImmutablePair) second}); 101 | } 102 | 103 | /** 104 | * Returns whether some other object "is equal" to this object. 105 | * 106 | * @param o reference object with which to compare 107 | * @return true if object is the same as the obj argument; false otherwise. 108 | */ 109 | @Override 110 | public boolean equals(Object o) { 111 | if (o == null) { 112 | return false; 113 | } 114 | if (!(o instanceof ImmutablePair)) { 115 | return false; 116 | } 117 | ImmutablePair other = (ImmutablePair) o; 118 | return Objects.equals(first, other.first) && Objects.equals(second, other.second); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/java/org/wso2/carbon/config/utils/EnvironmentUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.wso2.carbon.config.utils; 18 | 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | 22 | import java.lang.reflect.Field; 23 | import java.util.Arrays; 24 | import java.util.Collections; 25 | import java.util.HashMap; 26 | import java.util.Map; 27 | 28 | /** 29 | * Utility class for setting environment variables for test cases. 30 | * 31 | * @since 1.0.0 32 | */ 33 | public class EnvironmentUtils { 34 | private static Logger logger = LoggerFactory.getLogger(EnvironmentUtils.class); 35 | 36 | private static final String PROCESS_ENVIRONMENT = "java.lang.ProcessEnvironment"; 37 | private static final String THE_ENVIRONMENT_FILED = "theEnvironment"; 38 | private static final String THE_CASE_INSENSITIVE_ENVIRONMENT = "theCaseInsensitiveEnvironment"; 39 | private static final String COLLECTIONS_UNMODIFIABLE_MAP = "java.util.Collections$UnmodifiableMap"; 40 | private static final String FIELD_M = "m"; 41 | 42 | /** 43 | * Set environment variable for a given key and value. 44 | * 45 | * @param key Environment variable key. 46 | * @param value Environment variable value. 47 | */ 48 | public static void setEnvironmentVariables(String key, String value) { 49 | Map newEnv = new HashMap<>(); 50 | newEnv.put(key, value); 51 | setEnvironmentVariables(newEnv); 52 | } 53 | 54 | /** 55 | * Set environment variable from given map. 56 | * 57 | * @param newVariables Map of variables to put into environment variables. 58 | */ 59 | public static void setEnvironmentVariables(Map newVariables) { 60 | Map newEnv = new HashMap<>(); 61 | newEnv.putAll(System.getenv()); 62 | newEnv.putAll(newVariables); 63 | setEnvVariables(newEnv); 64 | } 65 | 66 | /** 67 | * Unset environment variable for a given key. 68 | * 69 | * @param key Environment variable key. 70 | */ 71 | public static void unsetEnvironmentVariables(String key) { 72 | Map newEnv = new HashMap<>(); 73 | newEnv.putAll(System.getenv()); 74 | newEnv.remove(key); 75 | setEnvVariables(newEnv); 76 | } 77 | 78 | /** 79 | * Set environment variable from given map. 80 | * 81 | * @param environmentVariables Map of variables to put into environment variables. 82 | */ 83 | private static void setEnvVariables(Map environmentVariables) { 84 | try { 85 | Class processEnvironmentClass = Class.forName(PROCESS_ENVIRONMENT); 86 | 87 | Field theEnvironmentField = processEnvironmentClass.getDeclaredField(THE_ENVIRONMENT_FILED); 88 | theEnvironmentField.setAccessible(true); 89 | Map env = (Map) theEnvironmentField.get(null); 90 | env.putAll(environmentVariables); 91 | 92 | Field theCaseInsensitiveEnvironmentField = processEnvironmentClass 93 | .getDeclaredField(THE_CASE_INSENSITIVE_ENVIRONMENT); 94 | theCaseInsensitiveEnvironmentField.setAccessible(true); 95 | Map caseInsensitiveEnv = (Map) theCaseInsensitiveEnvironmentField.get(null); 96 | caseInsensitiveEnv.putAll(environmentVariables); 97 | } catch (NoSuchFieldException e) { 98 | Class[] classes = Collections.class.getDeclaredClasses(); 99 | Map env = System.getenv(); 100 | Arrays.stream(classes).filter(cl -> COLLECTIONS_UNMODIFIABLE_MAP.equals(cl.getName())).forEach( 101 | (cl) -> { 102 | try { 103 | Field field = cl.getDeclaredField(FIELD_M); 104 | field.setAccessible(true); 105 | Object obj = field.get(env); 106 | Map map = (Map) obj; 107 | map.clear(); 108 | map.putAll(environmentVariables); 109 | } catch (IllegalAccessException | NoSuchFieldException ex) { 110 | logger.error("Unable to set environment variable via unmodifiable map", ex); 111 | } 112 | } 113 | ); 114 | } catch (ClassNotFoundException | IllegalAccessException e) { 115 | logger.error("Unable to set environment variable", e); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/java/org/wso2/carbon/config/UtilsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config; 17 | 18 | import org.testng.Assert; 19 | import org.testng.annotations.DataProvider; 20 | import org.testng.annotations.Test; 21 | import org.wso2.carbon.config.utils.EnvironmentUtils; 22 | 23 | /** 24 | * This class tests the functionality of ConfigurationUtils class. 25 | * 26 | * @since 1.0.0 27 | */ 28 | public class UtilsTest { 29 | 30 | private static final String UTIL_ENV = "util.test"; 31 | 32 | @Test 33 | public void testSubstituteVarsSystemPropertyNotNull() { 34 | String testVariable = System.getProperty(UTIL_ENV); 35 | boolean isTestVariableChanged = false; 36 | 37 | if (testVariable == null) { 38 | testVariable = "utils-test-variable"; 39 | System.setProperty(UTIL_ENV, testVariable); 40 | isTestVariableChanged = true; 41 | } 42 | 43 | Assert.assertEquals(ConfigurationUtils.substituteVariables("${util.test}"), testVariable); 44 | 45 | if (isTestVariableChanged) { 46 | System.clearProperty(UTIL_ENV); 47 | } 48 | } 49 | 50 | @Test 51 | public void testValueSubstituteVariables() { 52 | String testVariable = System.getProperty(UTIL_ENV); 53 | boolean isTestVariableChanged = false; 54 | 55 | if (testVariable == null) { 56 | testVariable = "utils-test-variable"; 57 | System.setProperty(UTIL_ENV, testVariable); 58 | isTestVariableChanged = true; 59 | } 60 | 61 | Assert.assertEquals(ConfigurationUtils.substituteVariables("ValueNotExist"), "ValueNotExist"); 62 | if (isTestVariableChanged) { 63 | System.clearProperty(UTIL_ENV); 64 | } 65 | } 66 | 67 | @Test(expectedExceptions = RuntimeException.class) 68 | public void testSubstituteVarsSystemPropertyIsNull() { 69 | String testVariable = System.getProperty(UTIL_ENV); 70 | boolean isTestVariableChanged = false; 71 | 72 | if (testVariable != null) { 73 | System.clearProperty(UTIL_ENV); 74 | isTestVariableChanged = true; 75 | } 76 | 77 | try { 78 | ConfigurationUtils.substituteVariables("${util.test}"); 79 | } finally { 80 | if (isTestVariableChanged) { 81 | System.setProperty(UTIL_ENV, testVariable); 82 | } 83 | } 84 | } 85 | 86 | @Test 87 | public void testSetGetSystemVariableValue() { 88 | // Set system variables 89 | EnvironmentUtils.setEnvironmentVariables("testEnvironmentVariable", "EnvironmentVariable"); 90 | EnvironmentUtils.setEnvironmentVariables("server.key", "test-server"); 91 | // Get system variables 92 | Assert.assertEquals(ConfigurationUtils.getSystemVariableValue("testEnvironmentVariable", 93 | null), "EnvironmentVariable"); 94 | Assert.assertEquals(ConfigurationUtils.getSystemVariableValue("${server.key.not.exist}", 95 | null, ConfigConstants.PlaceHolders.class), 96 | null); 97 | Assert.assertEquals(ConfigurationUtils.getSystemVariableValue("server.key", 98 | null, ConfigConstants.PlaceHolders.class), 99 | "test-server"); 100 | } 101 | 102 | @DataProvider(name = "paths") 103 | public Object[][] createPaths() { 104 | return new Object[][]{{"/home/wso2/wso2carbon", "/"}, 105 | {"C:\\Users\\WSO2\\Desktop\\CARBON~1\\WSO2CA~1.0-S", "\\"}}; 106 | } 107 | 108 | @Test(dataProvider = "paths") 109 | public void testPathSubstitution(String path, String pathSeparator) { 110 | System.setProperty(UTIL_ENV, path); 111 | String config = "${" + UTIL_ENV + "}" + pathSeparator + "deployment" + pathSeparator; 112 | Assert.assertEquals(ConfigurationUtils.substituteVariables(config), 113 | path + pathSeparator + "deployment" + pathSeparator); 114 | } 115 | 116 | @DataProvider(name = "params") 117 | public Object[][] createParamValues() { 118 | return new Object[][]{{"C:\\Software\\WSO2*Kernal-5.0.0\\ws$o2\\wor%ker\\bin", 119 | "C\\:\\\\Software\\\\WSO2\\*Kernal\\-5.0.0\\\\ws\\$o2\\\\wor\\%ker\\\\bin"}, 120 | {null, null}}; 121 | } 122 | 123 | @Test(dataProvider = "params") 124 | public void testEscapeSpecialCharacters(String inputString, String expectedString) { 125 | String outputString = ConfigurationUtils.escapeSpecialCharacters(inputString); 126 | Assert.assertEquals(expectedString, outputString); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/java/org/wso2/carbon/config/ConfigProviderFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config; 17 | 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | import org.wso2.carbon.config.provider.ConfigProvider; 21 | import org.wso2.carbon.config.provider.ConfigProviderImpl; 22 | import org.wso2.carbon.config.reader.ConfigFileReader; 23 | import org.wso2.carbon.config.reader.YAMLBasedConfigFileReader; 24 | import org.wso2.carbon.secvault.SecureVault; 25 | import org.wso2.carbon.secvault.SecureVaultFactory; 26 | import org.wso2.carbon.secvault.exception.SecureVaultException; 27 | 28 | import java.nio.file.Path; 29 | 30 | 31 | /** 32 | * This factory class will initialize and return configProvider instance. 33 | * 34 | * @since 1.0.0 35 | */ 36 | public class ConfigProviderFactory { 37 | 38 | private static final String YAML_EXTENSION = ".yaml"; 39 | private static Logger logger = LoggerFactory.getLogger(ConfigProviderFactory.class); 40 | 41 | /** 42 | * Initializes and returns configuration provider service from the configuration file provided. 43 | * 44 | * @param filePath configuration absolute filepath(e.g: {carbon-home}/conf/deployment.yaml}) 45 | * @return configProvider service object. 46 | * @throws ConfigurationException if an error occurred while initializing the config provider. 47 | */ 48 | public static ConfigProvider getConfigProvider(Path filePath) throws ConfigurationException { 49 | return getConfigProvider(filePath, getSecureVault(filePath)); 50 | } 51 | 52 | /** 53 | * Initializes and returns configuration provider service with the provided configuration file. 54 | * 55 | * @param filePath configuration absolute filepath(e.g: {carbon-home}/conf/deployment.yaml}) 56 | * @param secureVault {@code SecureVault>} 57 | * @return configProvider service object 58 | * @throws ConfigurationException if filepath == null or securevault == null or configuration file extension is 59 | * not equal to xml or yaml. 60 | */ 61 | public static ConfigProvider getConfigProvider(Path filePath, SecureVault secureVault) throws 62 | ConfigurationException { 63 | //check whether configuration filepath is null. proceed if not null. 64 | if (filePath == null || !filePath.toFile().exists()) { 65 | throw new ConfigurationException("No configuration filepath is provided. configuration provider will " + 66 | "not be initialized!"); 67 | } 68 | //check whether securevault is null. proceed if not null. 69 | if (secureVault == null) { 70 | logger.debug("No securevault service found. configuration provider will not be initialized!"); 71 | } 72 | if (logger.isDebugEnabled()) { 73 | logger.debug("initialize config provider instance from configuration file: " + filePath.toString()); 74 | } 75 | // initialize config provider service from the configuration file provided. 76 | ConfigFileReader configFileReader; 77 | if (filePath.toString().endsWith(YAML_EXTENSION)) { 78 | configFileReader = new YAMLBasedConfigFileReader(filePath); 79 | } else { 80 | throw new ConfigurationException("Error while initializing configuration provider, file extension is not " + 81 | "supported"); 82 | } 83 | return new ConfigProviderImpl(configFileReader, secureVault); 84 | } 85 | 86 | /** 87 | * Load {@code SecureVault} implementation in non-osgi mode. 88 | * 89 | * @param filePath configuration absolute filepath(e.g: {carbon-home}/conf/deployment.yaml}) 90 | * @throws ConfigurationException if an error occurred while loading securevault service. 91 | */ 92 | private static SecureVault getSecureVault(Path filePath) throws ConfigurationException { 93 | //check whether configuration filepath is null. proceed if not null. 94 | if (filePath == null || !filePath.toFile().exists()) { 95 | throw new ConfigurationException("Configuration filepath is not provided. configuration provider will " + 96 | "not be initialized!"); 97 | } 98 | if (logger.isDebugEnabled()) { 99 | logger.debug("initialize securevault instance from configuration file: " + filePath.toString()); 100 | } 101 | try { 102 | return SecureVaultFactory.getSecureVault(filePath).orElseThrow(() -> new ConfigurationException("Error " + 103 | "while loading securevault service")); 104 | } catch (SecureVaultException e) { 105 | throw new ConfigurationException("Error while loading securevault service", e); 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /tests/org.wso2.carbon.config.test/src/test/java/org/wso2/carbon/config/test/annotationprocessor/AnnotationProcessorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config.test.annotationprocessor; 17 | 18 | import org.apache.commons.io.FileUtils; 19 | import org.testng.Assert; 20 | import org.testng.annotations.AfterClass; 21 | import org.testng.annotations.BeforeClass; 22 | import org.testng.annotations.Test; 23 | import org.wso2.carbon.config.ConfigConstants; 24 | 25 | import java.io.ByteArrayOutputStream; 26 | import java.io.File; 27 | import java.io.IOException; 28 | import java.io.OutputStreamWriter; 29 | import java.nio.charset.Charset; 30 | import java.nio.file.Paths; 31 | import java.util.List; 32 | import java.util.Locale; 33 | import javax.tools.Diagnostic; 34 | import javax.tools.DiagnosticCollector; 35 | import javax.tools.JavaCompiler; 36 | import javax.tools.JavaFileObject; 37 | import javax.tools.StandardJavaFileManager; 38 | import javax.tools.ToolProvider; 39 | 40 | import static org.testng.Assert.fail; 41 | import static org.testng.AssertJUnit.assertEquals; 42 | 43 | /** 44 | * Tests the annotation processor logic in carbon core/annotations. 45 | * 46 | * @since 1.0.0 47 | */ 48 | public class AnnotationProcessorTest { 49 | 50 | private static JavaCompiler compiler; 51 | private StandardJavaFileManager fileManager; 52 | private DiagnosticCollector collector; 53 | private String[] classesToCompile; 54 | private String packagePath; 55 | 56 | @BeforeClass 57 | public void initClass() { 58 | //get the java compiler. 59 | compiler = ToolProvider.getSystemJavaCompiler(); 60 | //configure the diagnostics collector. 61 | collector = new DiagnosticCollector<>(); 62 | fileManager = compiler.getStandardFileManager(collector, Locale.US, Charset.forName("UTF-8")); 63 | packagePath = Paths.get("src", "test", "java", "org", "wso2", "carbon", "config", 64 | "test", "annotationprocessor").toString(); 65 | classesToCompile = new String[]{ 66 | Paths.get(packagePath, "TestConfiguration.java").toString()}; 67 | } 68 | 69 | @Test 70 | public void testCompilation() { 71 | try (ByteArrayOutputStream stdoutStream = new ByteArrayOutputStream(); 72 | OutputStreamWriter stdout = new OutputStreamWriter(stdoutStream)) { 73 | JavaCompiler.CompilationTask task = compiler.getTask(stdout, fileManager, collector, null, null, 74 | fileManager.getJavaFileObjects(classesToCompile)); 75 | Boolean result = task.call(); 76 | //perform the verifications. 77 | verifyCompilationErrors(collector.getDiagnostics(), result); 78 | verifyTempConfigFile(); 79 | } catch (IOException e) { 80 | Assert.fail("error while creating output stream.", e); 81 | } 82 | } 83 | 84 | private void verifyCompilationErrors(List> diagnostics, Boolean result) { 85 | //no mandatory warnings or compilation errors should be found. 86 | for (Diagnostic diagnostic : diagnostics) { 87 | if (diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING || 88 | diagnostic.getKind() == Diagnostic.Kind.ERROR) { 89 | fail("Failed with message: " + diagnostic.getMessage(null)); 90 | } 91 | } 92 | assertEquals("Files should have no compilation errors", Boolean.TRUE, result); 93 | } 94 | 95 | private void verifyTempConfigFile() { 96 | File file = Paths.get(System.getProperty("user.dir"), ConfigConstants.TEMP_CONFIG_FILE_NAME).toFile(); 97 | try { 98 | List lines = FileUtils.readLines(file, Charset.forName("UTF-8")); 99 | Assert.assertFalse(lines.isEmpty(), "temp config classes file cannot be empty"); 100 | 101 | boolean classFound = false; 102 | for (String line : lines) { 103 | if (line.contains("TestConfiguration")) { 104 | classFound = true; 105 | } 106 | } 107 | Assert.assertTrue(classFound, "expected configuration class doesnot exists"); 108 | } catch (IOException e) { 109 | Assert.fail("error while reading temp file.", e); 110 | } 111 | } 112 | 113 | @AfterClass 114 | public void cleanOutputs() throws IOException { 115 | File file = Paths.get(System.getProperty("user.dir"), ConfigConstants.TEMP_CONFIG_FILE_NAME).toFile(); 116 | FileUtils.forceDeleteOnExit(file); 117 | File classFile = Paths.get(System.getProperty("user.dir"), packagePath, "TestConfiguration.class").toFile(); 118 | FileUtils.forceDeleteOnExit(classFile); 119 | classFile = Paths.get(System.getProperty("user.dir"), packagePath, "Transport.class").toFile(); 120 | FileUtils.forceDeleteOnExit(classFile); 121 | classFile = Paths.get(System.getProperty("user.dir"), packagePath, "Transports.class").toFile(); 122 | FileUtils.forceDeleteOnExit(classFile); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | carbon-config 20 | org.wso2.carbon.config 21 | 2.1.18-SNAPSHOT 22 | ../../pom.xml 23 | 24 | 4.0.0 25 | org.wso2.carbon.config 26 | Carbon Configuration 27 | Carbon configuration is responsible for creating and manipulating 28 | 29 | bundle 30 | http://wso2.com 31 | 32 | 33 | org.wso2.eclipse.osgi 34 | org.eclipse.osgi 35 | 36 | 37 | org.wso2.eclipse.osgi 38 | org.eclipse.osgi.services 39 | 40 | 41 | org.slf4j 42 | slf4j-api 43 | 44 | 45 | org.yaml 46 | snakeyaml 47 | 48 | 49 | org.jacoco 50 | org.jacoco.agent 51 | runtime 52 | test 53 | 54 | 55 | org.easymock 56 | easymock 57 | test 58 | 59 | 60 | org.testng 61 | testng 62 | test 63 | 64 | 65 | org.wso2.carbon.secvault 66 | org.wso2.carbon.secvault 67 | 68 | 69 | org.wso2.carbon.utils 70 | org.wso2.carbon.utils 71 | 72 | 73 | com.github.spullara.mustache.java 74 | compiler 75 | 76 | 77 | 78 | 79 | 80 | maven-surefire-plugin 81 | false 82 | 83 | 84 | src/test/resources/testng.xml 85 | 86 | 87 | 88 | 89 | maven-compiler-plugin 90 | 91 | 1.8 92 | 1.8 93 | -proc:none 94 | 95 | 96 | 97 | org.jacoco 98 | jacoco-maven-plugin 99 | 100 | 101 | org.apache.maven.plugins 102 | maven-javadoc-plugin 103 | 104 | 105 | attach-javadocs 106 | 107 | jar 108 | 109 | 110 | -Xdoclint:none 111 | public 112 | true 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | true 121 | src/main/resources 122 | 123 | 124 | 125 | 126 | 127 | org.wso2.carbon.config.internal.*, 128 | com.github.mustachejava.* 129 | 130 | 131 | !org.wso2.carbon.config.internal.*, 132 | org.wso2.carbon.config.*;version="${carbon.config.version}" 133 | 134 | 135 | org.wso2.carbon.utils.*;version="${carbon.utils.package.import.version.range}", 136 | org.wso2.carbon.secvault.*;version="${carbon.securevault.version.range}", 137 | org.slf4j.*;version="${slf4j.logging.package.import.version.range}", 138 | org.osgi.framework.*;version="${osgi.framework.package.import.version.range}", 139 | org.yaml.snakeyaml.*;version="${org.snakeyaml.package.import.version.range}", 140 | com.github.mustachejava.*;version="${com.mustache.java.version.range}" 141 | 142 | 143 | -------------------------------------------------------------------------------- /samples/config-provider/standalone/src/main/java/org/wso2/carbon/config/samples/standalone/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.carbon.config.samples.standalone; 19 | 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | import org.wso2.carbon.config.ConfigProviderFactory; 23 | import org.wso2.carbon.config.ConfigurationException; 24 | import org.wso2.carbon.config.provider.ConfigProvider; 25 | import org.wso2.carbon.config.samples.ParentConfiguration; 26 | import org.wso2.carbon.secvault.SecureVaultConstants; 27 | 28 | import java.io.IOException; 29 | import java.io.InputStream; 30 | import java.nio.file.Files; 31 | import java.nio.file.Path; 32 | import java.nio.file.Paths; 33 | import java.util.Optional; 34 | 35 | /** 36 | * Main class for Carbon Config non-OSGi sample. 37 | */ 38 | public class Application { 39 | 40 | private static final Logger logger = LoggerFactory.getLogger(Application.class); 41 | private static final String FILE_FOLDER = "resources"; 42 | private static final String FILE_NAME = "deployment.yaml"; 43 | 44 | public static void main(String[] args) { 45 | copyFilesToPWD(); // Copies required files to the current working directory 46 | // Create new configuration provider 47 | Path deploymentConfigPath = Paths.get(FILE_FOLDER, "conf", FILE_NAME); 48 | 49 | // Get configuration 50 | try { 51 | ConfigProvider configProvider = ConfigProviderFactory.getConfigProvider(deploymentConfigPath); 52 | ParentConfiguration parentConfiguration = configProvider 53 | .getConfigurationObject(ParentConfiguration.class); 54 | logger.info("Parent configuration - {}", parentConfiguration); 55 | } catch (ConfigurationException e) { 56 | logger.error("Error in getting configuration", e); 57 | } 58 | } 59 | 60 | 61 | /** 62 | * Copy required files to the current working directory for demo purpose. 63 | * This method will only copy the files out of from security for demonstration purpose. 64 | */ 65 | private static void copyFilesToPWD() { 66 | 67 | Path deploymentYamlPath = Paths.get("conf", FILE_NAME); 68 | Path masterKeysPaths = Paths.get("conf", SecureVaultConstants.MASTER_KEYS_FILE_NAME); 69 | Path secretPropertiesPath = Paths.get("conf", SecureVaultConstants.SECRETS_PROPERTIES_FILE_NAME); 70 | Path jksResourcePath = Paths.get("security", "wso2carbon.jks"); 71 | 72 | // Copy config files 73 | try { 74 | Files.createDirectories(Paths.get(FILE_FOLDER, "conf")); 75 | Files.createDirectories(Paths.get(FILE_FOLDER, "security")); 76 | } catch (IOException e) { 77 | logger.error("Error occurred in creating directories", e); 78 | } 79 | 80 | // copy deployment.yaml file to resources/conf directory 81 | if (Files.notExists(Paths.get(FILE_FOLDER, deploymentYamlPath.toString()))) { 82 | try (InputStream deploymentYamlInputStream = getResourceInputStream(deploymentYamlPath) 83 | .orElseThrow(() -> new IOException("Error in copying " + FILE_NAME))) { 84 | Files.copy(deploymentYamlInputStream, Paths.get(FILE_FOLDER, deploymentYamlPath.toString())); 85 | } catch (IOException e) { 86 | logger.error("Error occurred in copying files", e); 87 | } 88 | } 89 | 90 | // copy master-keys.yaml file to resources/conf directory 91 | if (Files.notExists(Paths.get(FILE_FOLDER, masterKeysPaths.toString()))) { 92 | try (InputStream masterKeyInputStream = getResourceInputStream(masterKeysPaths) 93 | .orElseThrow(() -> new IOException("Error in copying " + 94 | SecureVaultConstants.MASTER_KEYS_FILE_NAME))) { 95 | Files.copy(masterKeyInputStream, Paths.get(FILE_FOLDER, masterKeysPaths.toString())); 96 | } catch (IOException e) { 97 | logger.error("Error occurred in copying files", e); 98 | } 99 | } 100 | 101 | // copy secrete.properties file to resources/conf directory 102 | if (Files.notExists(Paths.get(FILE_FOLDER, secretPropertiesPath.toString()))) { 103 | try (InputStream secretPropertiesInputStream = getResourceInputStream(secretPropertiesPath) 104 | .orElseThrow(() -> new IOException("Error in copying " + 105 | SecureVaultConstants.SECRETS_PROPERTIES_FILE_NAME))) { 106 | Files.copy(secretPropertiesInputStream, Paths.get(FILE_FOLDER, secretPropertiesPath.toString())); 107 | } catch (IOException e) { 108 | logger.error("Error occurred in copying files", e); 109 | } 110 | } 111 | 112 | // copy wso2carbon.jks file to resources/security directory 113 | if (Files.notExists(Paths.get(FILE_FOLDER, jksResourcePath.toString()))) { 114 | try (InputStream jksInputStream = getResourceInputStream(jksResourcePath) 115 | .orElseThrow(() -> new IOException("Error in copying file wso2carbon.jks"))) { 116 | Files.copy(jksInputStream, Paths.get(FILE_FOLDER, jksResourcePath.toString())); 117 | } catch (IOException e) { 118 | logger.error("Error occurred in copying files", e); 119 | } 120 | } 121 | } 122 | 123 | /** 124 | * Get input stream from the given resource. 125 | * 126 | * @param resourcePaths resource paths 127 | * @return input stream of the resource 128 | */ 129 | private static Optional getResourceInputStream(Path resourcePaths) { 130 | InputStream inputStream = Application.class.getClassLoader() 131 | .getResourceAsStream(resourcePaths.toString()); 132 | return Optional.ofNullable(inputStream); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/test/java/org/wso2/carbon/config/configprovider/ConfigProviderFactoryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config.configprovider; 17 | 18 | import org.easymock.EasyMock; 19 | import org.testng.Assert; 20 | import org.testng.annotations.AfterClass; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | import org.wso2.carbon.config.ConfigProviderFactory; 24 | import org.wso2.carbon.config.ConfigurationException; 25 | import org.wso2.carbon.config.provider.ConfigProvider; 26 | import org.wso2.carbon.secvault.SecureVault; 27 | import org.wso2.carbon.secvault.exception.SecureVaultException; 28 | 29 | import java.net.URISyntaxException; 30 | import java.nio.file.Path; 31 | 32 | /** 33 | * This class is to test uses of the ConfigProviderFactory. 34 | * 35 | * @since 1.0.0 36 | */ 37 | public class ConfigProviderFactoryTest { 38 | private static final String SYS_KEY_MASTER_KEY_FILE = "master.key.file"; 39 | private static final String SYS_KEY_SEC_PROP_FILE = "sec.prop.file"; 40 | private static final String SYS_KEY_KEYSTORE_FILE = "keystore.file"; 41 | private static final String PASSWORD = "n3wP4s5w0r4"; 42 | private SecureVault secureVault; 43 | private Path configPath; 44 | 45 | @BeforeTest 46 | public void setup() throws ConfigurationException, URISyntaxException { 47 | System.setProperty(SYS_KEY_MASTER_KEY_FILE, TestUtils.getResourcePath("conf", "master-keys.yaml").get() 48 | .toString()); 49 | System.setProperty(SYS_KEY_SEC_PROP_FILE, TestUtils.getResourcePath("conf", "secrets.properties").get() 50 | .toString()); 51 | System.setProperty(SYS_KEY_KEYSTORE_FILE, TestUtils.getResourcePath("conf", "wso2carbon.jks").get().toString()); 52 | 53 | secureVault = EasyMock.mock(SecureVault.class); 54 | try { 55 | EasyMock.expect(secureVault.resolve(EasyMock.anyString())).andReturn(PASSWORD.toCharArray()).anyTimes(); 56 | } catch (SecureVaultException e) { 57 | throw new ConfigurationException("Error resolving secure vault", e); 58 | } 59 | EasyMock.replay(secureVault); 60 | } 61 | 62 | @AfterClass 63 | public void clean() { 64 | System.clearProperty(SYS_KEY_MASTER_KEY_FILE); 65 | System.clearProperty(SYS_KEY_SEC_PROP_FILE); 66 | System.clearProperty(SYS_KEY_KEYSTORE_FILE); 67 | } 68 | 69 | @Test(description = "test case when file path is not provided, when getting config provider", expectedExceptions 70 | = ConfigurationException.class, expectedExceptionsMessageRegExp = "No configuration filepath is provided." + 71 | " configuration provider will not be initialized!") 72 | public void filePathNotProvidedTestCase() throws ConfigurationException { 73 | ConfigProviderFactory.getConfigProvider(null, secureVault); 74 | } 75 | 76 | @Test(description = "test case when file path is incorrect, when getting config provider", expectedExceptions 77 | = ConfigurationException.class, expectedExceptionsMessageRegExp = "No configuration filepath is provided." + 78 | " configuration provider will not be initialized!") 79 | public void incorrectFilePathTestCase() throws ConfigurationException { 80 | ConfigProviderFactory.getConfigProvider(TestUtils.getResourcePath("conf", "incorrectfilepath.yaml").get(), 81 | secureVault); 82 | } 83 | 84 | @Test(description = "test case when securevault is not provided, when getting config provider") 85 | public void secureVaultNotProvidedTestCase() throws ConfigurationException { 86 | Assert.assertNotNull( 87 | ConfigProviderFactory.getConfigProvider(TestUtils.getResourcePath("conf", "Example.yaml").get(), null), 88 | "Couldn't initialize ConfigProvider without Secvault"); 89 | } 90 | 91 | @Test(description = "test case for xml configuration file", expectedExceptions = ConfigurationException.class) 92 | public void xmlConfigFileTestCase() throws ConfigurationException { 93 | ConfigProvider configProvider = ConfigProviderFactory.getConfigProvider(TestUtils.getResourcePath("conf", 94 | "Example.xml").get(), 95 | secureVault); 96 | } 97 | 98 | @Test(description = "test case for yaml configuration file") 99 | public void yamlConfigFileTestCase() throws ConfigurationException { 100 | ConfigProvider configProvider = ConfigProviderFactory.getConfigProvider(TestUtils.getResourcePath("conf", 101 | "Example.yaml").get(), 102 | secureVault); 103 | Assert.assertNotNull(configProvider, "Configuration provider cannot be null"); 104 | } 105 | 106 | @Test(description = "test case for .txt configuration file. ", expectedExceptions = ConfigurationException.class, 107 | expectedExceptionsMessageRegExp = "Error while initializing configuration provider, file extension is not" + 108 | " supported") 109 | public void invalidConfigFileTestCase() throws ConfigurationException { 110 | ConfigProviderFactory.getConfigProvider(TestUtils.getResourcePath("conf", "Example.txt").get(), 111 | secureVault); 112 | } 113 | 114 | @Test(description = "test case for config provider when securevault is not predefined. yaml configuration file " + 115 | "contains securevault configuration") 116 | public void secureVaultNotPredefinedTestCase() throws ConfigurationException { 117 | 118 | ConfigProvider configProvider = ConfigProviderFactory.getConfigProvider(TestUtils.getResourcePath("conf", 119 | "deployment.yaml").get()); 120 | Assert.assertNotNull(configProvider, "Configuration provider cannot be null"); 121 | TestConfiguration testConfiguration = configProvider.getConfigurationObject(TestConfiguration.class); 122 | Assert.assertEquals(testConfiguration.getTenant(), "tenant"); 123 | } 124 | 125 | 126 | } 127 | -------------------------------------------------------------------------------- /tests/org.wso2.carbon.config.test.coverage/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | carbon-config 20 | org.wso2.carbon.config 21 | 2.1.18-SNAPSHOT 22 | ../../pom.xml 23 | 24 | 4.0.0 25 | org.wso2.carbon.config.test.coverage 26 | Carbon Configuration Coverage Reports 27 | Coverage Report for Carbon Configuration by merging unit and osgi tests 28 | 29 | http://wso2.com 30 | 31 | 32 | org.jacoco 33 | org.jacoco.ant 34 | test 35 | 36 | 37 | 38 | 39 | with-tests 40 | 41 | 42 | !maven.test.skip 43 | 44 | 45 | 46 | 47 | 48 | org.apache.maven.plugins 49 | maven-dependency-plugin 50 | 51 | 52 | copy-jacoco-dependencies 53 | compile 54 | 55 | copy-dependencies 56 | 57 | 58 | ${project.build.directory} 59 | jar 60 | org.jacoco.ant 61 | true 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | org.apache.maven.plugins 70 | maven-antrun-plugin 71 | 72 | 73 | package 74 | 75 | run 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | org.jacoco 110 | org.jacoco.ant 111 | ${org.jacoco.ant.version} 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/java/org/wso2/carbon/config/reader/ConfigFileReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.carbon.config.reader; 19 | 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | import org.wso2.carbon.config.ConfigConstants; 23 | import org.wso2.carbon.config.ConfigurationException; 24 | 25 | import java.io.BufferedReader; 26 | import java.io.File; 27 | import java.io.FileInputStream; 28 | import java.io.IOException; 29 | import java.io.InputStream; 30 | import java.io.InputStreamReader; 31 | import java.nio.charset.StandardCharsets; 32 | import java.nio.file.Files; 33 | import java.nio.file.Path; 34 | import java.nio.file.Paths; 35 | import java.util.ArrayList; 36 | import java.util.List; 37 | import java.util.Map; 38 | 39 | /** 40 | * Interface for reading a configuration file. 41 | * 42 | * @since 1.0.0 43 | */ 44 | public abstract class ConfigFileReader { 45 | 46 | private static final Logger log = LoggerFactory.getLogger(ConfigFileReader.class); 47 | private Path configurationFilePath; 48 | 49 | public ConfigFileReader(Path configurationFilePath) { 50 | this.configurationFilePath = configurationFilePath; 51 | } 52 | 53 | /** 54 | * Returns a populated Deployment Configuration Map which overrides default configuration. 55 | * 56 | * @return a instance of the Configuration Map, key: String, value: YAML string 57 | * @throws ConfigurationException if error occur while reading the configuration file. 58 | */ 59 | public abstract Map getDeploymentConfiguration() 60 | throws ConfigurationException; 61 | 62 | /** 63 | * Get contents of the file as a string. 64 | * 65 | * @return contents of the file as a string 66 | * @throws ConfigurationException if file name is null or on error on reading file 67 | */ 68 | public final String getFileContent() throws ConfigurationException { 69 | if (configurationFilePath == null) { 70 | String message = "Error while reading the configuration file, file path is null"; 71 | log.error(message); 72 | throw new ConfigurationException(message); 73 | } 74 | String customConfig = System.getProperty("config"); 75 | String customConfigContent; 76 | if (customConfig != null && (!customConfig.trim().isEmpty())) { 77 | try { 78 | // Change relative paths to absolute 79 | Path customConfigGivenPath = Paths.get(customConfig); 80 | if (!customConfigGivenPath.isAbsolute()) { 81 | if (System.getProperty(ConfigConstants.CURRENT_DIRECTORY) != null) { 82 | Path currentWorkingDirectory = Paths.get( 83 | System.getProperty(ConfigConstants.CURRENT_DIRECTORY) 84 | ).toAbsolutePath(); 85 | customConfig = currentWorkingDirectory.resolve( 86 | customConfigGivenPath.toString() 87 | ).normalize().toString(); 88 | } 89 | } 90 | File customDeploymentFile = new File(customConfig); 91 | if (customDeploymentFile.isFile()) { 92 | log.info("Default deployment configuration updated with provided custom configuration file " + 93 | customDeploymentFile.getName()); 94 | customConfigContent = getStringContentFromFile(customDeploymentFile); 95 | } else { 96 | customConfigContent = customConfig; 97 | } 98 | List configContentList = new ArrayList<>(); 99 | File defaultConfigFile = new File(configurationFilePath.toString()); 100 | String defaultConfigContent = getStringContentFromFile(defaultConfigFile); 101 | configContentList.add(defaultConfigContent); 102 | configContentList.add(customConfigContent); 103 | YmlMerger ymlMerger = new YmlMerger(); 104 | ymlMerger.setVariablesToReplace(System.getenv()); 105 | return ymlMerger.mergeToString(configContentList); 106 | } catch (IOException e) { 107 | String message = "Error occurred while overriding the default deployment configuration with provided" + 108 | "custom configurations."; 109 | log.error(message); 110 | throw new ConfigurationException(message, e); 111 | } 112 | } else { 113 | try { 114 | byte[] contentBytes = Files.readAllBytes(configurationFilePath); 115 | return new String(contentBytes, StandardCharsets.UTF_8); 116 | } catch (IOException e) { 117 | String message = "Error while reading configuration file"; 118 | log.error(message, e); 119 | throw new ConfigurationException(message, e); 120 | } 121 | } 122 | } 123 | 124 | private String getStringContentFromFile(File inputFile) throws IOException { 125 | InputStream inputStream = null; 126 | BufferedReader bufferedReader = null; 127 | StringBuilder inputSB = new StringBuilder(); 128 | try { 129 | inputStream = new FileInputStream(inputFile); 130 | bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); 131 | String line = bufferedReader.readLine(); 132 | while (line != null) { 133 | inputSB.append(line); 134 | line = bufferedReader.readLine(); 135 | if (line != null) { 136 | // add new line character 137 | inputSB.append("\n"); 138 | } 139 | } 140 | } finally { 141 | if (bufferedReader != null) { 142 | bufferedReader.close(); 143 | } 144 | if (inputStream != null) { 145 | inputStream.close(); 146 | } 147 | } 148 | return inputSB.toString(); 149 | } 150 | 151 | /** 152 | * Get configuration file path. 153 | * 154 | * @return configuration file path 155 | */ 156 | public Path getConfigurationFilePath() { 157 | return configurationFilePath; 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/java/org/wso2/carbon/config/reader/YmlMerger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.carbon.config.reader; 20 | 21 | import com.github.mustachejava.DefaultMustacheFactory; 22 | import org.slf4j.Logger; 23 | import org.slf4j.LoggerFactory; 24 | import org.yaml.snakeyaml.DumperOptions; 25 | import org.yaml.snakeyaml.Yaml; 26 | 27 | import java.io.StringReader; 28 | import java.io.StringWriter; 29 | import java.util.HashMap; 30 | import java.util.LinkedHashMap; 31 | import java.util.List; 32 | import java.util.Map; 33 | import java.util.TimeZone; 34 | 35 | /** 36 | * Merge multiple YML files into a single file, and substitute for any environment variables found. 37 | */ 38 | public class YmlMerger { 39 | 40 | private static final Logger LOG = LoggerFactory.getLogger(YmlMerger.class); 41 | private static final DefaultMustacheFactory DEFAULT_MUSTACHE_FACTORY = new DefaultMustacheFactory(); 42 | 43 | private final Yaml snakeYaml; 44 | private Map variablesToReplace = new HashMap(); 45 | 46 | public YmlMerger() { 47 | DumperOptions dumperOptions = new DumperOptions(); 48 | dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); 49 | dumperOptions.setPrettyFlow(true); 50 | 51 | dumperOptions.setTimeZone(TimeZone.getTimeZone("UTC")); 52 | this.snakeYaml = new Yaml(dumperOptions); 53 | } 54 | 55 | public YmlMerger setVariablesToReplace(Map vars) { 56 | this.variablesToReplace.clear(); 57 | this.variablesToReplace.putAll(vars); 58 | return this; 59 | } 60 | 61 | /** 62 | * Merges the files at given paths to a map representing the resulting YAML structure. 63 | */ 64 | @SuppressWarnings("unchecked") 65 | private Map mergeYamlContents(List contents) { 66 | Map mergedResult = new LinkedHashMap(); 67 | for (String yamlContent : contents) { 68 | // Substitute variables. 69 | int bufferSize = yamlContent.length() + 100; 70 | final StringWriter writer = new StringWriter(bufferSize); 71 | DEFAULT_MUSTACHE_FACTORY.compile(new StringReader(yamlContent), "yaml-mergeYamlFiles-" + 72 | System.currentTimeMillis()).execute(writer, variablesToReplace); 73 | 74 | // Parse the YAML. 75 | String yamlString = writer.toString(); 76 | final Map yamlToMerge = (Map) this.snakeYaml.load(yamlString); 77 | 78 | // Merge into results map. 79 | mergeStructures(mergedResult, yamlToMerge); 80 | } 81 | return mergedResult; 82 | } 83 | 84 | @SuppressWarnings("unchecked") 85 | private void mergeStructures(Map targetTree, Map sourceTree) { 86 | if (sourceTree == null) { 87 | return; 88 | } 89 | 90 | for (Map.Entry entry : sourceTree.entrySet()) { 91 | Object yamlValue = entry.getValue(); 92 | String key = entry.getKey().toString(); 93 | if (yamlValue == null) { 94 | addToMergedResult(targetTree, key, null); 95 | continue; 96 | } 97 | 98 | Object existingValue = targetTree.get(key); 99 | if (existingValue != null) { 100 | if (yamlValue instanceof Map) { 101 | if (existingValue instanceof Map) { 102 | mergeStructures((Map) existingValue, (Map) yamlValue); 103 | } else if (existingValue instanceof String) { 104 | throw new IllegalArgumentException("Cannot merge Yaml files; complex element into a " + 105 | "simple element: " + key); 106 | } else { 107 | throw unknownValueType(key, yamlValue); 108 | } 109 | } else if (yamlValue instanceof List) { 110 | mergeLists(targetTree, key, yamlValue); 111 | } else if (yamlValue instanceof String 112 | || yamlValue instanceof Boolean 113 | || yamlValue instanceof Double 114 | || yamlValue instanceof Integer) { 115 | LOG.debug("Overriding value of " + key + " with value " + yamlValue); 116 | addToMergedResult(targetTree, key, yamlValue); 117 | 118 | } else { 119 | throw unknownValueType(key, yamlValue); 120 | } 121 | 122 | } else { 123 | if (yamlValue instanceof Map 124 | || yamlValue instanceof List 125 | || yamlValue instanceof String 126 | || yamlValue instanceof Boolean 127 | || yamlValue instanceof Integer 128 | || yamlValue instanceof Double) { 129 | LOG.debug("Adding new key->value: " + key + " -> " + yamlValue); 130 | addToMergedResult(targetTree, key, yamlValue); 131 | } else { 132 | throw unknownValueType(key, yamlValue); 133 | } 134 | } 135 | } 136 | } 137 | 138 | private static IllegalArgumentException unknownValueType(String key, Object yamlValue) { 139 | final String msg = "Cannot merge Yaml files; element of unknown type: " + key + ": " + 140 | yamlValue.getClass().getName(); 141 | LOG.error(msg); 142 | return new IllegalArgumentException(msg); 143 | } 144 | 145 | private static void addToMergedResult(Map mergedResult, String key, Object yamlValue) { 146 | mergedResult.put(key, yamlValue); 147 | } 148 | 149 | @SuppressWarnings("unchecked") 150 | private static void mergeLists(Map mergedResult, String key, Object yamlValue) { 151 | if (!(yamlValue instanceof List && mergedResult.get(key) instanceof List)) { 152 | throw new IllegalArgumentException("Cannot merge Yaml files; list with a non-list: " + key); 153 | } 154 | 155 | List originalList = (List) mergedResult.get(key); 156 | originalList.clear(); 157 | originalList.addAll((List) yamlValue); 158 | } 159 | 160 | 161 | String mergeToString(List contentToMerge) { 162 | Map merged = mergeYamlContents(contentToMerge); 163 | return exportToString(merged); 164 | } 165 | 166 | private String exportToString(Map merged) { 167 | return snakeYaml.dump(merged); 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /components/org.wso2.carbon.config/src/main/java/org/wso2/carbon/config/ConfigurationUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wso2.carbon.config; 17 | 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | import org.yaml.snakeyaml.DumperOptions; 21 | import org.yaml.snakeyaml.Yaml; 22 | import org.yaml.snakeyaml.nodes.Tag; 23 | 24 | import java.io.IOException; 25 | import java.io.InputStream; 26 | import java.lang.reflect.Field; 27 | import java.util.HashMap; 28 | import java.util.Locale; 29 | import java.util.Map; 30 | import java.util.Properties; 31 | import java.util.regex.Matcher; 32 | import java.util.regex.Pattern; 33 | 34 | /** 35 | * Configuration internal utils. 36 | * 37 | * @since 1.0.0 38 | */ 39 | public class ConfigurationUtils { 40 | 41 | private static final Logger logger = LoggerFactory.getLogger(ConfigurationUtils.class); 42 | private static final Pattern varPattern = Pattern.compile("\\$\\{([^}]*)}"); 43 | private static final char[] specialCharArray = new char[]{'\\', '+', '-', '!', '(', ')', ':', '^', '[', ']', 44 | '\"', '{', '}', '~', '*', '?', '|', '&', ';', '/', '$', '%'}; 45 | 46 | private ConfigurationUtils() { 47 | } 48 | 49 | /** 50 | * This method converts the yaml string to configuration map. 51 | * Map contains, key : yaml (root)key 52 | * values : yaml string of the key 53 | * 54 | * @param yamlString yaml string 55 | * @return configuration map 56 | */ 57 | public static Map getDeploymentConfigMap(String yamlString) { 58 | Map deploymentConfigs = new HashMap<>(); 59 | Yaml yaml = new Yaml(); 60 | Map map = (Map) yaml.loadAs(yamlString, Map.class); 61 | 62 | map.entrySet().stream() 63 | .filter(entry -> entry.getValue() != null) 64 | .forEach((entry) -> { 65 | String yamlValue; 66 | if (entry.getValue() instanceof Map) { 67 | yamlValue = yaml.dumpAsMap(entry.getValue()); 68 | } else { 69 | yamlValue = yaml.dumpAs(entry.getValue(), Tag.SEQ, DumperOptions.FlowStyle.BLOCK); 70 | } 71 | deploymentConfigs.put(entry.getKey(), yamlValue); 72 | }); 73 | return deploymentConfigs; 74 | } 75 | 76 | /** 77 | * This method reads project properties in resource file. 78 | * 79 | * @return project properties 80 | */ 81 | public static Properties loadProjectProperties() { 82 | Properties properties = new Properties(); 83 | try (InputStream in = ConfigurationUtils.class.getClassLoader().getResourceAsStream(ConfigConstants 84 | .PROJECT_DEFAULTS_PROPERTY_FILE)) { 85 | if (in != null) { 86 | properties.load(in); 87 | } 88 | } catch (IOException e) { 89 | logger.error("Error while reading the project default properties, hence apply default values.", e); 90 | } 91 | return properties; 92 | } 93 | 94 | /** 95 | * Replace system property holders in the property values. 96 | * e.g. Replace ${carbon.home} with value of the carbon.home system property. 97 | * 98 | * @param value string value to substitute 99 | * @return String substituted string 100 | */ 101 | public static String substituteVariables(String value) { 102 | // Fix the issue #3, This method should not execute in doc generation phase. Need not substitute vaule. 103 | // Check the system property to identify the call is coming in doc generation phase. 104 | if (Boolean.getBoolean(ConfigConstants.SYSTEM_PROPERTY_DOC_GENERATION)) { 105 | return value; 106 | } 107 | 108 | Matcher matcher = varPattern.matcher(value); 109 | boolean found = matcher.find(); 110 | if (!found) { 111 | return value; 112 | } 113 | StringBuffer sb = new StringBuffer(); 114 | do { 115 | String sysPropKey = matcher.group(1); 116 | String sysPropValue = getSystemVariableValue(sysPropKey, null); 117 | if (sysPropValue == null || sysPropValue.length() == 0) { 118 | String msg = "System property " + sysPropKey + " is not specified"; 119 | logger.error(msg); 120 | throw new RuntimeException(msg); 121 | } 122 | // Due to reported bug under CARBON-14746 123 | sysPropValue = sysPropValue.replace("\\", "\\\\"); 124 | matcher.appendReplacement(sb, sysPropValue); 125 | } while (matcher.find()); 126 | matcher.appendTail(sb); 127 | return sb.toString(); 128 | } 129 | 130 | /** 131 | * A utility which allows reading variables from the environment or System properties. 132 | * If the variable in available in the environment as well as a System property, the System property takes 133 | * precedence. 134 | * 135 | * @param variableName System/environment variable name 136 | * @param defaultValue default value to be returned if the specified system variable is not specified. 137 | * @return value of the system/environment variable 138 | */ 139 | public static String getSystemVariableValue(String variableName, String defaultValue) { 140 | return getSystemVariableValue(variableName, defaultValue, ConfigConstants.PlaceHolders.class); 141 | } 142 | 143 | /** 144 | * A utility which allows reading variables from the environment or System properties. 145 | * If the variable in available in the environment as well as a System property, the System property takes 146 | * precedence. 147 | * 148 | * @param variableName System/environment variable name 149 | * @param defaultValue default value to be returned if the specified system variable is not specified. 150 | * @param constantClass Class from which the Predefined value should be retrieved if system variable and default 151 | * value is not specified. 152 | * @return value of the system/environment variable 153 | */ 154 | public static String getSystemVariableValue(String variableName, String defaultValue, Class constantClass) { 155 | String value = null; 156 | if (System.getProperty(variableName) != null) { 157 | value = System.getProperty(variableName); 158 | } else if (System.getenv(variableName) != null) { 159 | value = System.getenv(variableName); 160 | } else { 161 | try { 162 | String constant = variableName.replaceAll("\\.", "_").toUpperCase(Locale.getDefault()); 163 | Field field = constantClass.getField(constant); 164 | value = (String) field.get(constant); 165 | } catch (NoSuchFieldException | IllegalAccessException e) { 166 | //Nothing to do 167 | } 168 | if (value == null) { 169 | value = defaultValue; 170 | } 171 | } 172 | return value; 173 | } 174 | 175 | /** 176 | * Returns replace value with escaped characters. 177 | * 178 | * @param value replaced values 179 | * @return value with escaped characters 180 | */ 181 | public static String escapeSpecialCharacters(String value) { 182 | if (value == null) { 183 | return null; 184 | } 185 | StringBuilder sb = new StringBuilder(); 186 | for (int i = 0; i < value.length(); i++) { 187 | char c = value.charAt(i); 188 | 189 | boolean charExists = false; 190 | for (char s : specialCharArray) { 191 | if (c == s) { 192 | charExists = true; 193 | } 194 | } 195 | if (charExists || Character.isWhitespace(c)) { 196 | sb.append('\\'); 197 | } 198 | sb.append(c); 199 | } 200 | return sb.toString(); 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /docs/ConfigurationsViaEnvironmentVariables.md: -------------------------------------------------------------------------------- 1 | # Configurations via environment variables / system properties 2 | 3 | In a containerized environments, maintaining multiple configurations for each and every container is not reliable. This is due to, 4 | 5 | * Maintaining multiple configurations for multiple containers is a cumbersome task. 6 | * Most of the configurations could be duplicated among configuration files. 7 | * Even if a single configuration file is to be maintained, the physical file needs to be edited in order to suit the required configuration for a specific container, thus would violate the immutable nature of containerization. 8 | 9 | In order to overcome the above, configurations can be provided via environment variables or system properties following a specific pattern. 10 | 11 | ## Priority order when building the configuration 12 | 13 | ![Priority order when building the configuration](images/ConfigurationsViaEnvironmentVariables/SysVarPriority.png) 14 | 15 | System properties / environment variables could be used to override deployment.yaml configurations or add new configurations. This is mostly useful in containerized environments to overcome the above mentioned limitations. 16 | 17 | ## Environment variable / system property pattern 18 | 19 | `_=""` 20 | 21 | ![Environment variable / system property structure](images/ConfigurationsViaEnvironmentVariables/VarStructure.png) 22 | 23 | #### Example 1: 24 | 25 | Consider the below YAML configuration. 26 | 27 | ```yaml 28 | wso2.configuration: 29 | complexBean: 30 | name: default 31 | Bean: 32 | name: default 33 | ``` 34 | 35 | The above configuration can be represented with the below environment variables / system properties: 36 | 37 | ```bash 38 | WSO2_CONFIGURATION__COMPLEXTESTBEAN_NAME="default" 39 | WSO2_CONFIGURATION__COMPLEXTESTBEAN_BEAN_NAME="default" 40 | ``` 41 | 42 | Where, 43 | 44 | * NAMESPACE = `wso2.configuration` 45 | 46 | ___ 47 | **Notes:** 48 | 49 | * As a convention (refer [environment variable / system property pattern](#user-content-environment-variable--system-property-pattern)), 50 | * The environment variable names / system property names should be in all caps. 51 | * The environment variable / system property segments should be separated by an underscore ("_"). 52 | ___ 53 | 54 | #### Example 2: 55 | 56 | Consider the below YAML configuration. 57 | 58 | ```yaml 59 | testconfiguration: 60 | tenant: tenant 61 | transports: 62 | transport: 63 | - name: abc 64 | port: 8000 65 | secure: false 66 | desc: This transport will use 8000 as its port 67 | password: password 68 | - name: pqr 69 | port: 8001 70 | secure: true 71 | desc: This transport will use 8001 as its port. Secure - true 72 | - name: xyz 73 | port: 9000 74 | secure: true 75 | desc: This transport will use 9000 as its port 76 | ``` 77 | 78 | The above configuration can be represented with the below environment variables / system properties: 79 | 80 | ```bash 81 | TESTCONFIGURATION_TENANT="tenant" 82 | 83 | # Transport "abc" 84 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_NAME="abc" 85 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_PORT="8000" 86 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_SECURE="false" 87 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_DESC="This transport will use 8000 as its port" 88 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_PASSWORD="password" 89 | 90 | # Transport "pqr" 91 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_NAME="pqr" 92 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_PORT="8001" 93 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_SECURE="true" 94 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_DESC="This transport will use 8001 as its port. Secure - true" 95 | 96 | # Transport "xyz" 97 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_NAME="xyz" 98 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_PORT="9000" 99 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_SECURE="true" 100 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_DESC="This transport will use 9000 as its port" 101 | ``` 102 | 103 | Where, 104 | 105 | * NAMESPACE = `testconfiguration` 106 | 107 | ___ 108 | **Notes:** 109 | 110 | * As a convention (refer [environment variable / system property pattern](#user-content-environment-variable--system-property-pattern)), 111 | * The environment variable names / system property names should be in all caps. 112 | * The environment variable / system property segments should be separated by an underscore ("_"). 113 | * Array elements are identified with the separation of a positive integer. 114 | * **Each array element should be able to be identified via a unique property in the array element.** 115 | **In this example, we can identify "NAME" as a unique property (each transport can be identified with it's name).** 116 | This unique property is used internally to identify each transport in the overriding process. 117 | ___ 118 | 119 | ## Specifying the unique identifiable property for configuration arrays 120 | 121 | By default, the unique identifiable attribute is either "ID" or "NAME" ("ID" has the highest priority). If both 122 | these attributes are not present, you can specify the unique identifiable attribute via an environment 123 | variable (Refer [Example 3](#user-content-example-3---specifying-unique-identifiable-property-via-an-environment-variable--system-properties)) 124 | 125 | #### Example 1: 126 | 127 | Consider the below YAML configuration. 128 | 129 | ```yaml 130 | testconfiguration: 131 | tenant: tenant 132 | transports: 133 | transport: 134 | - name: abc 135 | port: 8000 136 | secure: false 137 | desc: This transport will use 8000 as its port 138 | password: password 139 | - name: pqr 140 | port: 8001 141 | secure: true 142 | desc: This transport will use 8001 as its port. Secure - true 143 | - name: xyz 144 | port: 9000 145 | secure: true 146 | desc: This transport will use 9000 as its port 147 | ``` 148 | The above configuration can be represented with the below environment variables / system properties: 149 | 150 | ```bash 151 | TESTCONFIGURATION_TENANT="tenant" 152 | 153 | # Transport "abc" 154 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_NAME="abc" 155 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_PORT="8000" 156 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_SECURE="false" 157 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_DESC="This transport will use 8000 as its port" 158 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_PASSWORD="password" 159 | 160 | # Transport "pqr" 161 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_NAME="pqr" 162 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_PORT="8001" 163 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_SECURE="true" 164 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_DESC="This transport will use 8001 as its port. Secure - true" 165 | 166 | # Transport "xyz" 167 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_NAME="xyz" 168 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_PORT="9000" 169 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_SECURE="true" 170 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_DESC="This transport will use 9000 as its port" 171 | ``` 172 | 173 | Where, 174 | 175 | * NAMESPACE = `testconfiguration` 176 | * Each transport is identified uniquely with the "NAME" attribute (ex: TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_NAME). 177 | 178 | #### Example 2: 179 | 180 | Consider the below YAML configuration. 181 | 182 | ```yaml 183 | testconfiguration: 184 | tenant: tenant 185 | transports: 186 | transport: 187 | - name: abc 188 | id: 001 189 | port: 8000 190 | secure: false 191 | desc: This transport will use 8000 as its port 192 | password: password 193 | - name: pqr 194 | id: 002 195 | port: 8001 196 | secure: true 197 | desc: This transport will use 8001 as its port. Secure - true 198 | - name: xyz 199 | id: 003 200 | port: 9000 201 | secure: true 202 | desc: This transport will use 9000 as its port 203 | ``` 204 | The above configuration can be represented with the below environment variables / system properties: 205 | 206 | ```bash 207 | TESTCONFIGURATION_TENANT="tenant" 208 | 209 | # Transport "abc" 210 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_NAME="abc" 211 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_ID="001" 212 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_PORT="8000" 213 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_SECURE="false" 214 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_DESC="This transport will use 8000 as its port" 215 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_PASSWORD="password" 216 | 217 | # Transport "pqr" 218 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_NAME="pqr" 219 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_ID="002" 220 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_PORT="8001" 221 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_SECURE="true" 222 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_DESC="This transport will use 8001 as its port. Secure - true" 223 | 224 | # Transport "xyz" 225 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_NAME="xyz" 226 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_ID="003" 227 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_PORT="9000" 228 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_SECURE="true" 229 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_DESC="This transport will use 9000 as its port" 230 | ``` 231 | 232 | Where, 233 | 234 | * NAMESPACE = `testconfiguration` 235 | * Each transport is identified uniquely with the "ID" attribute (ex: TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_ID). **Even though "NAME" is also a candidate for the unique identifiable attribute, "ID" is chosen over "NAME" since "ID" has a higher priority.** 236 | 237 | #### Example 3 - specifying unique identifiable property via an environment variable / system properties: 238 | 239 | Consider the below YAML configuration. 240 | 241 | ```yaml 242 | testconfiguration: 243 | tenant: tenant 244 | transports: 245 | transport: 246 | - port: 8000 247 | uniqueKey: abc 248 | secure: false 249 | desc: This transport will use 8000 as its port 250 | password: password 251 | - port: 8001 252 | uniqueKey: pqr 253 | secure: true 254 | desc: This transport will use 8001 as its port. Secure - true 255 | - port: 9000 256 | uniqueKey: xyz 257 | secure: true 258 | desc: This transport will use 9000 as its port 259 | ``` 260 | The above configuration can be represented with the below environment variables / system properties: 261 | 262 | ```bash 263 | TESTCONFIGURATION_TENANT="tenant" 264 | 265 | # Transport "abc" 266 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_UNIQUEKEY="abc" 267 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_PORT="8000" 268 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_SECURE="false" 269 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_DESC="This transport will use 8000 as its port" 270 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_0_PASSWORD="password" 271 | 272 | # Transport "pqr" 273 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_UNIQUEKEY="pqr" 274 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_PORT="8001" 275 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_SECURE="true" 276 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_1_DESC="This transport will use 8001 as its port. Secure - true" 277 | 278 | # Transport "xyz" 279 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_UNIQUEKEY="xyz" 280 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_PORT="9000" 281 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_SECURE="true" 282 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_2_DESC="This transport will use 9000 as its port" 283 | ``` 284 | 285 | However, since "ID" and "NAME" attributes are not present, you have to specify your unique identifiable attribute name 286 | via an environment variable / system property. This variable name is suffixed with the "UNIQUE" keyword. 287 | 288 | ```bash 289 | TESTCONFIGURATION_TRANSPORTS_TRANSPORT_UNIQUE="UNIQUEKEY" 290 | ``` 291 | 292 | Where, 293 | 294 | * NAMESPACE = `testconfiguration` 295 | * Each transport is identified uniquely with the "UNIQUEKEY" attribute since it is specified via an environment variable / system property. 296 | -------------------------------------------------------------------------------- /samples/config-generator/README.md: -------------------------------------------------------------------------------- 1 | # Configuration Document Generation Sample 2 | 3 | ## Configuration annotations 4 | 5 | @Configuration annotation is used to define that the annotated class is a 6 | configuration. 7 | 8 | ```java 9 | @Configuration(namespace = "org.wso2.configuration", description = "Parent configuration") 10 | public class ParentConfiguration { 11 | 12 | } 13 | ``` 14 | 15 | `namespace` property is used to define a configuration section in the 16 | generated configuration. 17 | 18 | @Element annotation defines an element in the configuration file. 19 | However, even if this is not specified, all the private variables are 20 | by default considered as elements in the configuration. 21 | 22 | @ignore annotation specifically ignores the annotated variable being 23 | written to the prepared configuration file. 24 | 25 | ## Example 1 26 | 27 | ###Dependencies 28 | 29 | 30 | 31 | ```xml 32 | 33 | org.wso2.carbon.config 34 | org.wso2.carbon.config 35 | ${carbon.config.version} 36 | 37 | 38 | ``` 39 | 40 | This is the only dependency required when you want to create 41 | configuration POJO classes. This dependency will provide you with 42 | the configuration annotations and is also required by the 43 | `org.wso2.carbon.config.maven.plugin` plugin when generating the 44 | configuration files. 45 | 46 | ### Sample configuration POJO 47 | 48 | ```java 49 | @Configuration(namespace = "org.wso2.configuration", description = "Parent configuration") 50 | public class ParentConfiguration { 51 | 52 | @Element(description = "An example element for this configuration") 53 | private String name = "WSO2"; 54 | 55 | @Element(description = "Another example element in the config", required = true) 56 | private int value = 10; 57 | 58 | // This value will not be visible in the configuration 59 | @Ignore 60 | private String ignored = "Ignored String"; 61 | 62 | @Element(description = "Second level configuration") 63 | private ChildConfiguration childConfiguration = new ChildConfiguration(); 64 | 65 | public String getName() { 66 | return name; 67 | } 68 | 69 | public int getValue() { 70 | return value; 71 | } 72 | 73 | public String getIgnored() { 74 | return ignored; 75 | } 76 | 77 | public ChildConfiguration getChildConfiguration() { 78 | return childConfiguration; 79 | } 80 | 81 | @Override 82 | public String toString() { 83 | return String.format(Locale.ENGLISH, "name : %s, value : %s, childConfiguration - %s", 84 | name, value, childConfiguration); 85 | } 86 | } 87 | ``` 88 | 89 | ### pom configuration 90 | 91 | Add the below mentioned code segment to the \/\ section 92 | of the relevant pom. This will locate all the POJO classes **(within the pom's project only)** with @Configuration 93 | annotation to build the configuration file. 94 | 95 | ```xml 96 | 97 | org.wso2.carbon.config 98 | org.wso2.carbon.config.maven.plugin 99 | ${carbon.config.version} 100 | 101 | 102 | 103 | create-doc 104 | 105 | compile 106 | 107 | 108 | 109 | ``` 110 | 111 | If you want to create the configuration files for specified POJO 112 | classes specify the `` inside the `` 113 | element within the maven config plugin 114 | 115 | ```xml 116 | 117 | org.wso2.carbon.config 118 | org.wso2.carbon.config.maven.plugin 119 | ${carbon.config.version} 120 | 121 | 122 | 123 | create-doc 124 | 125 | compile 126 | 127 | 128 | 130 | 131 | 132 | 133 | org.wso2.carbon.config.samples.configgeneration.DemoConfiguration 134 | 135 | 136 | 137 | 138 | ``` 139 | 140 | This will only generate the configuration file to `org.wso2.carbon.config.samples.configgeneration.DemoConfiguration` 141 | class. You may specify multiple `configclass` elements inside the `configclasses` tag. 142 | 143 | ### Building the sample 144 | 145 | Navigate to [Configuration sample](/) and execute the command below: 146 | 147 | ```bash 148 | mvn clean install 149 | ``` 150 | 151 | ### Result of the above configuration POJO class 152 | 153 | ```yaml 154 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved 155 | # 156 | # Licensed under the Apache License, Version 2.0 (the \"License\"); 157 | # you may not use this file except in compliance with the License. 158 | # You may obtain a copy of the License at 159 | # 160 | # http://www.apache.org/licenses/LICENSE-2.0 161 | # 162 | # Unless required by applicable law or agreed to in writing, software 163 | # distributed under the License is distributed on an \"AS IS\" BASIS, 164 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 165 | # See the License for the specific language governing permissions and 166 | # limitations un: 167 | # Property with element tag 168 | propertyWithElement: Property 1 169 | # Integer property 170 | value: 20 171 | propertyWithoutElement: Property 3 172 | # Example required property 173 | # THIS IS A MANDATORY FIELD 174 | requiredProperty: Property 4nder the License. 175 | 176 | # This is a demo configuration 177 | demo.configuration: 178 | # Property with element tag 179 | propertyWithElement: Property 1 180 | # Integer property 181 | value: 20 182 | propertyWithoutElement: Property 3 183 | # Example required property 184 | # THIS IS A MANDATORY FIELD 185 | requiredProperty: Property 4 186 | ``` 187 | 188 | ## Example 2 189 | 190 | ### Dependencies and Plugins 191 | 192 | Add the following dependency and plugin to the project pom file. 193 | 194 | ```xml 195 | 196 | org.wso2.carbon.config 197 | org.wso2.carbon.config 198 | ${carbon.config.version} 199 | 200 | ``` 201 | ```xml 202 | 203 | org.wso2.carbon.config 204 | org.wso2.carbon.config.maven.plugin 205 | ${carbon.config.version} 206 | 207 | 208 | 209 | create-doc 210 | 211 | compile 212 | 213 | 214 | 215 | ``` 216 | 217 | ### Configuration POJO classes 218 | 219 | Add configuration annotations to the POJO classes which you need to generate configuration documents. In this Sample, 220 | there are two POJO classes(ParentConfiguration and ChildConfiguration). 221 | 222 | #### Parent Configuration 223 | 224 | ```java 225 | @Configuration(namespace = "org.wso2.configuration", description = "Parent configuration") 226 | public class ParentConfiguration { 227 | 228 | @Element(description = "An example element for this configuration") 229 | private String name = "WSO2"; 230 | 231 | @Element(description = "Another example element in the config", required = true) 232 | private int value = 10; 233 | 234 | // This value will not be visible in the configuration 235 | @Ignore 236 | private String ignored = "Ignored String"; 237 | 238 | @Element(description = "Second level configuration") 239 | private ChildConfiguration childConfiguration = new ChildConfiguration(); 240 | 241 | public String getName() { 242 | return name; 243 | } 244 | 245 | public int getValue() { 246 | return value; 247 | } 248 | 249 | public String getIgnored() { 250 | return ignored; 251 | } 252 | 253 | public ChildConfiguration getChildConfiguration() { 254 | return childConfiguration; 255 | } 256 | 257 | @Override 258 | public String toString() { 259 | return String.format(Locale.ENGLISH, "name : %s, value : %s, childConfiguration - %s", 260 | name, value, childConfiguration); 261 | } 262 | } 263 | ``` 264 | 265 | #### Child Configuration 266 | 267 | ```java 268 | // In here do not specify the namespace since this configuration is a part of the 269 | // ParentConfiguration. Specifying the namespace will break this configuration to a separate 270 | // configuration under the section of the specified namespace 271 | @Configuration(description = "Child configuration") 272 | public class ChildConfiguration { 273 | 274 | @Element(description = "A boolean field") 275 | private boolean isEnabled = false; 276 | 277 | @Element(description = "A string field") 278 | private String destination = "destination-name"; 279 | 280 | public boolean isEnabled() { 281 | return isEnabled; 282 | } 283 | 284 | public String getDestination() { 285 | return destination; 286 | } 287 | 288 | @Override 289 | public String toString() { 290 | return String.format(Locale.ENGLISH, "destination : %s, isEnabled : %s", 291 | destination, isEnabled); 292 | } 293 | } 294 | ``` 295 | 296 | **Note:** Since `ChildConfiguration` is a part of the `ParentConfiguration`, we do not need to specify the 297 | `namespace` property in the `@Configuration` annotation. Specifying the `namespace` property in the `@Configuration` 298 | annotation of the `ChildConfiguration` will break the `ChildConfiguration` to a new configuration section under the 299 | specified `namespace`. 300 | 301 | ### Building the sample 302 | 303 | Navigate to sample project and execute the command below: 304 | 305 | ```bash 306 | mvn clean install 307 | ``` 308 | 309 | ### Result configuration document 310 | 311 | Below configuration doc file can be located in the jar file under config-docs directory. 312 | 313 | ```yaml 314 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved 315 | # 316 | # Licensed under the Apache License, Version 2.0 (the \"License\"); 317 | # you may not use this file except in compliance with the License. 318 | # You may obtain a copy of the License at 319 | # 320 | # http://www.apache.org/licenses/LICENSE-2.0 321 | # 322 | # Unless required by applicable law or agreed to in writing, software 323 | # distributed under the License is distributed on an \"AS IS\" BASIS, 324 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 325 | # See the License for the specific language governing permissions and 326 | # limitations under the License. 327 | 328 | # Parent configuration 329 | wso2.configuration: 330 | # An example element for this configuration 331 | name: WSO2 332 | # Another example element in the config 333 | # THIS IS A MANDATORY FIELD 334 | value: 10 335 | # Child configuration 336 | childConfiguration: 337 | # A boolean field 338 | isEnabled: false 339 | # A string field 340 | destination: destination-name 341 | ``` --------------------------------------------------------------------------------