summaryrefslogtreecommitdiffstats
path: root/common/onap-common-configuration-management
diff options
context:
space:
mode:
Diffstat (limited to 'common/onap-common-configuration-management')
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-api/pom.xml15
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/Config.java21
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/Configuration.java831
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/ConfigurationChangeListener.java14
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/ConfigurationManager.java98
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/DynamicConfiguration.java146
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/Hint.java18
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-cli/pom.xml55
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-cli/src/main/java/org/onap/config/cli/app/Configuration.java119
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-cli/src/main/java/org/onap/config/gui/app/Configuration.java623
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/pom.xml128
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/ConfigurationUtils.java1144
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/Constants.java14
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/NonConfigResource.java95
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/AgglomerateConfiguration.java33
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/AggregateConfiguration.java172
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/CliConfigurationImpl.java354
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationChangeNotifier.java474
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationDataSource.java105
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationFilter.java39
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationImpl.java679
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationRepository.java415
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ContextListener.java28
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/YamlConfiguration.java18
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationMode.java5
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationQuery.java94
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationType.java5
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationUpdate.java33
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/resources/META-INF/services/org.onap.config.api.ConfigurationManager1
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/resources/config-system.properties22
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/main/resources/management.properties7
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-core/src/test/java/org/onap/config/ConfigurationUtilsTest.java32
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/pom.xml84
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/TestCMSuite.java76
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/CLIFallbackAndLookupTest.java83
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/CLITest.java108
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ConfigSourceLocationTest.java53
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/DynamicConfigurationTest.java66
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/FallbackConfigTest.java38
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/FallbackToGlobalNSTest.java42
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/GlobalAndNSConfigTest.java43
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/JAVAPropertiesConfigTest.java40
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/JSONConfigTest.java40
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/LoadOrderMergeAndOverrideTest.java46
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ModeAsConfigPropTest.java87
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/MultiTenancyConfigTest.java46
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/NodeSpecificCLITest.java117
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/NotificationForNodeConfigTest.java85
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/NotificationOnPropValTest.java76
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ResourceChangeNotificationTest.java88
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/UnregisterNotificationTest.java94
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ValidateDefaultModeTest.java58
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ValidateNodeConfigTest.java80
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/XMLConfigTest.java40
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/YAMLConfigTest.java40
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/util/ConfigTestConstant.java23
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/util/TestUtil.java91
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config-NS.properties12
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.json8
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.properties3
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.xml18
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.yaml8
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config-NS.properties12
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.json8
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.properties3
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.xml18
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.yaml8
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.json8
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.properties13
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.xml18
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.yaml8
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config-NS.properties13
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.json9
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.properties3
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.xml19
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.yaml8
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.json10
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.properties10
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.xml16
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.yaml7
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config-M.json16
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config-O.json11
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config-U.json11
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config.json30
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-M.properties9
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-O.properties7
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-U.properties5
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-loadorder-M.properties9
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-loadorder-O.properties7
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config.properties14
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.json8
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.properties10
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.xml16
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.yaml8
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NodeCLI/config.properties9
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/Notification/config.properties15
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig.zipbin0 -> 1705 bytes
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.json12
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.properties14
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.xml18
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.yaml8
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config-NS.properties13
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.json9
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.properties3
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.xml18
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.yaml9
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.json10
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.properties14
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.xml19
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.yaml8
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config-NS.properties13
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.json9
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.properties3
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.xml18
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.yaml9
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateDefaultMode/config-defaultmode.json8
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateDefaultMode/config-defaultmode.properties2
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateNodeConfig/config-NS.properties13
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateNodeConfig/config.properties3
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config-M.xml19
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config-O.xml14
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config-U.xml14
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config.xml25
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config-M.yaml12
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config-O.yaml8
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config-U.yaml8
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config.yaml27
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/config-system.properties22
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback-merge.xml15
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback-override.json7
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback-union.yaml5
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback.properties13
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config-M.properties7
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config-O.properties5
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config-U.properties5
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config.properties14
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config-at.properties11
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config-tf.properties10
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config-vf.properties11
-rw-r--r--common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config.properties11
-rw-r--r--common/onap-common-configuration-management/pom.xml30
141 files changed, 8432 insertions, 0 deletions
diff --git a/common/onap-common-configuration-management/onap-configuration-management-api/pom.xml b/common/onap-common-configuration-management/onap-configuration-management-api/pom.xml
new file mode 100644
index 0000000000..df2b77ba14
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-api/pom.xml
@@ -0,0 +1,15 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <name>onap-configuration-management-api</name>
+ <artifactId>onap-configuration-management-api</artifactId>
+
+ <parent>
+ <artifactId>onap-common-configuration-management</artifactId>
+ <groupId>org.onap.sdc.common</groupId>
+ <version>1.2.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+</project>
diff --git a/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/Config.java b/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/Config.java
new file mode 100644
index 0000000000..b4cd68df5d
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/Config.java
@@ -0,0 +1,21 @@
+package org.onap.config.api;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The interface Config.
+ */
+@Target({ElementType.TYPE, ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Config {
+
+ /**
+ * Key string.
+ *
+ * @return the string
+ */
+ String key() default "";
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/Configuration.java b/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/Configuration.java
new file mode 100644
index 0000000000..58eedd7575
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/Configuration.java
@@ -0,0 +1,831 @@
+package org.onap.config.api;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The interface Configuration.
+ */
+public interface Configuration {
+ /**
+ * The constant tenant.
+ */
+ public static ThreadLocal<String> tenant = new ThreadLocal<>();
+
+ /**
+ * Sets tenant id.
+ *
+ * @param id the id
+ */
+ public static void setTenantId(String id) {
+ if (id != null && id.trim().length() > 0) {
+ tenant.set(id);
+ }
+ }
+
+ /**
+ * Gets as string.
+ *
+ * @param key the key
+ * @return the as string
+ */
+ public default String getAsString(String key) {
+ return getAsString(null, key);
+ }
+
+ /**
+ * Gets as string.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as string
+ */
+ public default String getAsString(String namespace, String key) {
+ return getAsString(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as string.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as string
+ */
+ public default String getAsString(String tenantId, String namespace, String key) {
+ return get(tenantId, namespace, key, String.class);
+ }
+
+ /**
+ * Gets as byte value.
+ *
+ * @param key the key
+ * @return the as byte value
+ */
+ public default Byte getAsByteValue(String key) {
+ return getAsByteValue(null, key);
+ }
+
+ /**
+ * Gets as byte value.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as byte value
+ */
+ public default Byte getAsByteValue(String namespace, String key) {
+ return getAsByteValue(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as byte value.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as byte value
+ */
+ public default Byte getAsByteValue(String tenantId, String namespace, String key) {
+ return get(tenantId, namespace, key, Byte.class);
+ }
+
+ /**
+ * Gets as short value.
+ *
+ * @param key the key
+ * @return the as short value
+ */
+ public default Short getAsShortValue(String key) {
+ return getAsShortValue(null, key);
+ }
+
+ /**
+ * Gets as short value.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as short value
+ */
+ public default Short getAsShortValue(String namespace, String key) {
+ return getAsShortValue(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as short value.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as short value
+ */
+ public default Short getAsShortValue(String tenantId, String namespace, String key) {
+ return get(tenantId, namespace, key, Short.class);
+ }
+
+ /**
+ * Gets as integer value.
+ *
+ * @param key the key
+ * @return the as integer value
+ */
+ public default Integer getAsIntegerValue(String key) {
+ return getAsIntegerValue(null, key);
+ }
+
+ /**
+ * Gets as integer value.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as integer value
+ */
+ public default Integer getAsIntegerValue(String namespace, String key) {
+ return getAsIntegerValue(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as integer value.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as integer value
+ */
+ public default Integer getAsIntegerValue(String tenantId, String namespace, String key) {
+ return get(tenantId, namespace, key, Integer.class);
+ }
+
+ /**
+ * Gets as long value.
+ *
+ * @param key the key
+ * @return the as long value
+ */
+ public default Long getAsLongValue(String key) {
+ return getAsLongValue(null, key);
+ }
+
+ /**
+ * Gets as long value.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as long value
+ */
+ public default Long getAsLongValue(String namespace, String key) {
+ return getAsLongValue(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as long value.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as long value
+ */
+ public default Long getAsLongValue(String tenantId, String namespace, String key) {
+ return get(tenantId, namespace, key, Long.class);
+ }
+
+ /**
+ * Gets as float value.
+ *
+ * @param key the key
+ * @return the as float value
+ */
+ public default Float getAsFloatValue(String key) {
+ return getAsFloatValue(null, key);
+ }
+
+ /**
+ * Gets as float value.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as float value
+ */
+ public default Float getAsFloatValue(String namespace, String key) {
+ return getAsFloatValue(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as float value.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as float value
+ */
+ public default Float getAsFloatValue(String tenantId, String namespace, String key) {
+ return get(tenantId, namespace, key, Float.class);
+ }
+
+ /**
+ * Gets as double value.
+ *
+ * @param key the key
+ * @return the as double value
+ */
+ public default Double getAsDoubleValue(String key) {
+ return getAsDoubleValue(null, key);
+ }
+
+ /**
+ * Gets as double value.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as double value
+ */
+ public default Double getAsDoubleValue(String namespace, String key) {
+ return getAsDoubleValue(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as double value.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as double value
+ */
+ public default Double getAsDoubleValue(String tenantId, String namespace, String key) {
+ return get(tenantId, namespace, key, Double.class);
+ }
+
+ /**
+ * Gets as boolean value.
+ *
+ * @param key the key
+ * @return the as boolean value
+ */
+ public default Boolean getAsBooleanValue(String key) {
+ return getAsBooleanValue(null, key);
+ }
+
+ /**
+ * Gets as boolean value.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as boolean value
+ */
+ public default Boolean getAsBooleanValue(String namespace, String key) {
+ return getAsBooleanValue(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as boolean value.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as boolean value
+ */
+ public default Boolean getAsBooleanValue(String tenantId, String namespace, String key) {
+ return get(tenantId, namespace, key, Boolean.class);
+ }
+
+ /**
+ * Gets as char value.
+ *
+ * @param key the key
+ * @return the as char value
+ */
+ public default Character getAsCharValue(String key) {
+ return getAsCharValue(null, key);
+ }
+
+ /**
+ * Gets as char value.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as char value
+ */
+ public default Character getAsCharValue(String namespace, String key) {
+ return getAsCharValue(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as char value.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as char value
+ */
+ public default Character getAsCharValue(String tenantId, String namespace, String key) {
+ return get(tenantId, namespace, key, Character.class);
+ }
+
+ /**
+ * Populate configuration t.
+ *
+ * @param <T> the type parameter
+ * @param clazz the clazz
+ * @return the t
+ */
+ public default <T> T populateConfiguration(Class<T> clazz) {
+ return populateConfiguration(null, clazz);
+ }
+
+ /**
+ * Populate configuration t.
+ *
+ * @param <T> the type parameter
+ * @param namespace the namespace
+ * @param clazz the clazz
+ * @return the t
+ */
+ public default <T> T populateConfiguration(String namespace, Class<T> clazz) {
+ return populateConfiguration(tenant.get(), namespace, clazz);
+ }
+
+ /**
+ * Populate configuration t.
+ *
+ * @param <T> the type parameter
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param clazz the clazz
+ * @return the t
+ */
+ public default <T> T populateConfiguration(String tenantId, String namespace, Class<T> clazz) {
+ return get(tenantId, namespace, null, clazz, Hint.EXTERNAL_LOOKUP);
+ }
+
+ /**
+ * Gets dynamic configuration.
+ *
+ * @param <T> the type parameter
+ * @param key the key
+ * @param clazz the clazz
+ * @param defaultValue the default value
+ * @return the dynamic configuration
+ */
+ public default <T> DynamicConfiguration<T> getDynamicConfiguration(String key, Class<T> clazz,
+ T defaultValue) {
+ return getDynamicConfiguration(null, key, clazz, defaultValue);
+ }
+
+ /**
+ * Gets dynamic configuration.
+ *
+ * @param <T> the type parameter
+ * @param namespace the namespace
+ * @param key the key
+ * @param clazz the clazz
+ * @param defaultValue the default value
+ * @return the dynamic configuration
+ */
+ public default <T> DynamicConfiguration<T> getDynamicConfiguration(String namespace, String key,
+ Class<T> clazz,
+ T defaultValue) {
+ return getDynamicConfiguration(tenant.get(), namespace, key, clazz, defaultValue);
+ }
+
+ /**
+ * Gets dynamic configuration.
+ *
+ * @param <T> the type parameter
+ * @param tenant the tenant
+ * @param namespace the namespace
+ * @param key the key
+ * @param clazz the clazz
+ * @param defaultValue the default value
+ * @return the dynamic configuration
+ */
+ public default <T> DynamicConfiguration<T> getDynamicConfiguration(String tenant,
+ String namespace, String key,
+ Class<T> clazz,
+ T defaultValue) {
+ return DynamicConfiguration
+ .getDynamicConfiguration(tenant, namespace, key, clazz, defaultValue, this);
+ }
+
+ /**
+ * Gets dynamic configuration values.
+ *
+ * @param <T> the type parameter
+ * @param key the key
+ * @param clazz the clazz
+ * @param defaultValue the default value
+ * @return the dynamic configuration values
+ */
+ public default <T> DynamicConfiguration<List<T>> getDynamicConfigurationValues(String key,
+ Class<T> clazz,
+ T defaultValue) {
+ return getDynamicConfigurationValues(null, key, clazz, defaultValue);
+ }
+
+ /**
+ * Gets dynamic configuration values.
+ *
+ * @param <T> the type parameter
+ * @param namespace the namespace
+ * @param key the key
+ * @param clazz the clazz
+ * @param defaultValue the default value
+ * @return the dynamic configuration values
+ */
+ public default <T> DynamicConfiguration<List<T>> getDynamicConfigurationValues(String namespace,
+ String key,
+ Class<T> clazz,
+ T defaultValue) {
+ return getDynamicConfigurationValues(tenant.get(), namespace, key, clazz, defaultValue);
+ }
+
+ /**
+ * Gets dynamic configuration values.
+ *
+ * @param <T> the type parameter
+ * @param tenant the tenant
+ * @param namespace the namespace
+ * @param key the key
+ * @param clazz the clazz
+ * @param defaultValue the default value
+ * @return the dynamic configuration values
+ */
+ public default <T> DynamicConfiguration<List<T>> getDynamicConfigurationValues(String tenant,
+ String namespace,
+ String key,
+ Class<T> clazz,
+ T defaultValue) {
+ return DynamicConfiguration
+ .getDynConfiguration(tenant, namespace, key, clazz, defaultValue, this);
+ }
+
+ /**
+ * Gets as string values.
+ *
+ * @param key the key
+ * @return the as string values
+ */
+ public default List<String> getAsStringValues(String key) {
+ return getAsStringValues(null, key);
+ }
+
+ /**
+ * Gets as string values.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as string values
+ */
+ public default List<String> getAsStringValues(String namespace, String key) {
+ return getAsStringValues(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as string values.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as string values
+ */
+ public default List<String> getAsStringValues(String tenantId, String namespace, String key) {
+ String[] tempArray = get(tenantId, namespace, key, String[].class);
+ return tempArray == null ? Arrays.asList() : Arrays.asList(tempArray);
+ }
+
+ /**
+ * Gets as byte values.
+ *
+ * @param key the key
+ * @return the as byte values
+ */
+ public default List<Byte> getAsByteValues(String key) {
+ return getAsByteValues(null, key);
+ }
+
+ /**
+ * Gets as byte values.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as byte values
+ */
+ public default List<Byte> getAsByteValues(String namespace, String key) {
+ return getAsByteValues(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as byte values.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as byte values
+ */
+ public default List<Byte> getAsByteValues(String tenantId, String namespace, String key) {
+ Byte[] tempArray = get(tenantId, namespace, key, Byte[].class);
+ return tempArray == null ? Arrays.asList() : Arrays.asList(tempArray);
+ }
+
+ /**
+ * Gets as short values.
+ *
+ * @param key the key
+ * @return the as short values
+ */
+ public default List<Short> getAsShortValues(String key) {
+ return getAsShortValues(null, key);
+ }
+
+ /**
+ * Gets as short values.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as short values
+ */
+ public default List<Short> getAsShortValues(String namespace, String key) {
+ return getAsShortValues(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as short values.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as short values
+ */
+ public default List<Short> getAsShortValues(String tenantId, String namespace, String key) {
+ Short[] tempArray = get(tenantId, namespace, key, Short[].class);
+ return tempArray == null ? Arrays.asList() : Arrays.asList(tempArray);
+ }
+
+ /**
+ * Gets as integer values.
+ *
+ * @param key the key
+ * @return the as integer values
+ */
+ public default List<Integer> getAsIntegerValues(String key) {
+ return getAsIntegerValues(null, key);
+ }
+
+ /**
+ * Gets as integer values.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as integer values
+ */
+ public default List<Integer> getAsIntegerValues(String namespace, String key) {
+ return getAsIntegerValues(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as integer values.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as integer values
+ */
+ public default List<Integer> getAsIntegerValues(String tenantId, String namespace, String key) {
+ Integer[] tempArray = get(tenantId, namespace, key, Integer[].class);
+ return tempArray == null ? Arrays.asList() : Arrays.asList(tempArray);
+ }
+
+ /**
+ * Gets as double values.
+ *
+ * @param key the key
+ * @return the as double values
+ */
+ public default List<Double> getAsDoubleValues(String key) {
+ return getAsDoubleValues(null, key);
+ }
+
+ /**
+ * Gets as double values.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as double values
+ */
+ public default List<Double> getAsDoubleValues(String namespace, String key) {
+ return getAsDoubleValues(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as double values.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as double values
+ */
+ public default List<Double> getAsDoubleValues(String tenantId, String namespace, String key) {
+ Double[] tempArray = get(tenantId, namespace, key, Double[].class);
+ return tempArray == null ? Arrays.asList() : Arrays.asList(tempArray);
+ }
+
+ /**
+ * Gets as float values.
+ *
+ * @param key the key
+ * @return the as float values
+ */
+ public default List<Float> getAsFloatValues(String key) {
+ return getAsFloatValues(null, key);
+ }
+
+ /**
+ * Gets as float values.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as float values
+ */
+ public default List<Float> getAsFloatValues(String namespace, String key) {
+ return getAsFloatValues(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as float values.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as float values
+ */
+ public default List<Float> getAsFloatValues(String tenantId, String namespace, String key) {
+ Float[] tempArray = get(tenantId, namespace, key, Float[].class);
+ return tempArray == null ? Arrays.asList() : Arrays.asList(tempArray);
+ }
+
+ /**
+ * Gets as boolean values.
+ *
+ * @param key the key
+ * @return the as boolean values
+ */
+ public default List<Boolean> getAsBooleanValues(String key) {
+ return getAsBooleanValues(null, key);
+ }
+
+ /**
+ * Gets as boolean values.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as boolean values
+ */
+ public default List<Boolean> getAsBooleanValues(String namespace, String key) {
+ return getAsBooleanValues(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as boolean values.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as boolean values
+ */
+ public default List<Boolean> getAsBooleanValues(String tenantId, String namespace, String key) {
+ Boolean[] tempArray = get(tenantId, namespace, key, Boolean[].class);
+ return tempArray == null ? Arrays.asList() : Arrays.asList(tempArray);
+ }
+
+ /**
+ * Gets as character values.
+ *
+ * @param key the key
+ * @return the as character values
+ */
+ public default List<Character> getAsCharacterValues(String key) {
+ return getAsCharacterValues(null, key);
+ }
+
+ /**
+ * Gets as character values.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as character values
+ */
+ public default List<Character> getAsCharacterValues(String namespace, String key) {
+ return getAsCharacterValues(tenant.get(), namespace, key);
+ }
+
+ /**
+ * Gets as character values.
+ *
+ * @param tenantId the tenant id
+ * @param namespace the namespace
+ * @param key the key
+ * @return the as character values
+ */
+ public default List<Character> getAsCharacterValues(String tenantId, String namespace,
+ String key) {
+ Character[] tempArray = get(tenantId, namespace, key, Character[].class);
+ return tempArray == null ? Arrays.asList() : Arrays.asList(tempArray);
+ }
+
+ /**
+ * Get t.
+ *
+ * @param <T> the type parameter
+ * @param tenant the tenant
+ * @param namespace the namespace
+ * @param key the key
+ * @param clazz the clazz
+ * @param hints the hints
+ * @return the t
+ */
+ public <T> T get(String tenant, String namespace, String key, Class<T> clazz, Hint... hints);
+
+ /**
+ * Add configuration change listener.
+ *
+ * @param key the key
+ * @param myself the myself
+ */
+ public default void addConfigurationChangeListener(String key,
+ ConfigurationChangeListener myself) {
+ addConfigurationChangeListener(null, key, myself);
+ }
+
+ /**
+ * Add configuration change listener.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @param myself the myself
+ */
+ public default void addConfigurationChangeListener(String namespace, String key,
+ ConfigurationChangeListener myself) {
+ addConfigurationChangeListener(tenant.get(), namespace, key, myself);
+ }
+
+ /**
+ * Add configuration change listener.
+ *
+ * @param tenant the tenant
+ * @param namespace the namespace
+ * @param key the key
+ * @param myself the myself
+ */
+ public void addConfigurationChangeListener(String tenant, String namespace, String key,
+ ConfigurationChangeListener myself);
+
+ /**
+ * Remove configuration change listener.
+ *
+ * @param key the key
+ * @param myself the myself
+ */
+ public default void removeConfigurationChangeListener(String key,
+ ConfigurationChangeListener myself) {
+ removeConfigurationChangeListener(null, key, myself);
+ }
+
+ /**
+ * Remove configuration change listener.
+ *
+ * @param namespace the namespace
+ * @param key the key
+ * @param myself the myself
+ */
+ public default void removeConfigurationChangeListener(String namespace, String key,
+ ConfigurationChangeListener myself) {
+ removeConfigurationChangeListener(tenant.get(), namespace, key, myself);
+ }
+
+ /**
+ * Remove configuration change listener.
+ *
+ * @param tenant the tenant
+ * @param namespace the namespace
+ * @param key the key
+ * @param myself the myself
+ */
+ public void removeConfigurationChangeListener(String tenant, String namespace, String key,
+ ConfigurationChangeListener myself);
+
+ public default <T> Map<String, T> populateMap(String key, Class<T> clazz){
+ return populateMap(null, key, clazz);
+ }
+ public default <T> Map<String, T> populateMap(String namespace, String key, Class<T> clazz){
+ return populateMap(tenant.get(), namespace, key, clazz);
+ }
+ public <T> Map<String, T> populateMap(String tenantId, String namespace, String key, Class<T> clazz);
+
+ public default Map generateMap(String key){
+ return generateMap(null, key);
+ }
+ public default Map generateMap(String namespace, String key){
+ return generateMap(tenant.get(), namespace, key);
+ }
+ public Map generateMap(String tenantId, String namespace, String key);
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/ConfigurationChangeListener.java b/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/ConfigurationChangeListener.java
new file mode 100644
index 0000000000..451a75f3ae
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/ConfigurationChangeListener.java
@@ -0,0 +1,14 @@
+package org.onap.config.api;
+
+public interface ConfigurationChangeListener {
+
+ public default void notify(String tenantId, String component, String key, Object oldValue,
+ Object newValue) {
+ }
+
+ public default void notify(String component, String key, Object oldValue, Object newValue) {
+ }
+
+ public default void notify(String key, Object oldValue, Object newValue) {
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/ConfigurationManager.java b/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/ConfigurationManager.java
new file mode 100644
index 0000000000..0e8f1409a0
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/ConfigurationManager.java
@@ -0,0 +1,98 @@
+package org.onap.config.api;
+
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
+import java.util.Collection;
+import java.util.Map;
+import java.util.ServiceLoader;
+
+/**
+ * The interface Configuration manager.
+ */
+public interface ConfigurationManager extends Configuration {
+
+ /**
+ * The constant config.
+ */
+ public static final Configuration config = lookup();
+
+ /**
+ * Lookup configuration.
+ *
+ * @return the configuration
+ */
+ public static Configuration lookup() {
+ if (config == null) {
+ ServiceLoader<ConfigurationManager> loader = ServiceLoader.load(ConfigurationManager.class);
+ for (ConfigurationManager configuration : loader) {
+ return (Configuration) Proxy.newProxyInstance(ConfigurationManager.class.getClassLoader(),
+ new Class[]{Configuration.class}, (object, method, args) -> {
+ try {
+ return method.invoke(configuration, args);
+ } catch (InvocationTargetException ite) {
+ throw ite.getTargetException();
+ }
+ });
+ }
+ }
+ return config;
+ }
+
+ /**
+ * Gets configuration value.
+ *
+ * @param queryData the query data
+ * @return the configuration value
+ */
+ public String getConfigurationValue(Map<String, Object> queryData);
+
+ /**
+ * Update configuration value.
+ *
+ * @param updateData the update data
+ */
+ public void updateConfigurationValue(Map<String, Object> updateData);
+
+ /**
+ * List configuration map.
+ *
+ * @param query the query
+ * @return the map
+ */
+ public Map<String, String> listConfiguration(Map<String, Object> query);
+
+ /**
+ * Update configuration values boolean.
+ *
+ * @param tenant the tenant
+ * @param namespace the namespace
+ * @param configKeyValueStore the config key value store
+ * @return the boolean
+ */
+ public boolean updateConfigurationValues(String tenant, String namespace,
+ Map configKeyValueStore);
+
+ /**
+ * Gets tenants.
+ *
+ * @return the tenants
+ */
+ public Collection<String> getTenants();
+
+ /**
+ * Gets namespaces.
+ *
+ * @return the namespaces
+ */
+ public Collection<String> getNamespaces();
+
+ /**
+ * Gets keys.
+ *
+ * @param tenant the tenant
+ * @param namespace the namespace
+ * @return the keys
+ */
+ public Collection<String> getKeys(String tenant, String namespace);
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/DynamicConfiguration.java b/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/DynamicConfiguration.java
new file mode 100644
index 0000000000..969749b260
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/DynamicConfiguration.java
@@ -0,0 +1,146 @@
+package org.onap.config.api;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * The type Dynamic configuration.
+ *
+ * @param <T> the type parameter
+ */
+public class DynamicConfiguration<T> {
+
+ /**
+ * The Tenant.
+ */
+ String tenant;
+ /**
+ * The Namespace.
+ */
+ String namespace;
+ /**
+ * The Key.
+ */
+ String key;
+ /**
+ * The Configuration.
+ */
+ Configuration configuration;
+ /**
+ * The Clazz.
+ */
+ Class clazz;
+ /**
+ * The Default value.
+ */
+ T defaultValue;
+
+ /**
+ * Gets dynamic configuration.
+ *
+ * @param <T> the type parameter
+ * @param tenant the tenant
+ * @param namespace the namespace
+ * @param key the key
+ * @param clazz the clazz
+ * @param defaultValue the default value
+ * @param configuration the configuration
+ * @return the dynamic configuration
+ */
+ public static <T> DynamicConfiguration<T> getDynamicConfiguration(String tenant, String namespace,
+ String key, Class<T> clazz,
+ T defaultValue,
+ Configuration configuration) {
+ DynamicConfiguration<T> dynamicConfiguration = new DynamicConfiguration<>();
+ dynamicConfiguration.tenant = tenant;
+ dynamicConfiguration.namespace = namespace;
+ dynamicConfiguration.key = key;
+ dynamicConfiguration.clazz = clazz;
+ dynamicConfiguration.defaultValue = defaultValue;
+ dynamicConfiguration.configuration = configuration;
+ return dynamicConfiguration;
+ }
+
+ /**
+ * Gets dyn configuration.
+ *
+ * @param <K> the type parameter
+ * @param tenant the tenant
+ * @param namespace the namespace
+ * @param key the key
+ * @param clazz the clazz
+ * @param defaultValue the default value
+ * @param configuration the configuration
+ * @return the dyn configuration
+ */
+ public static <K> DynamicConfiguration<List<K>> getDynConfiguration(String tenant,
+ String namespace, String key,
+ Class<K> clazz,
+ K defaultValue,
+ Configuration configuration) {
+ if (clazz.isPrimitive()) {
+ throw new RuntimeException(
+ "Only Wrapper classes like Integer, Long, Double, "
+ + "Boolean etc including String are supported.");
+ }
+ return getDynamicConfiguration(tenant, namespace, key, getArrayClass(clazz),
+ Arrays.asList(defaultValue), configuration);
+ }
+
+ /**
+ * Gets array class.
+ *
+ * @param clazz the clazz
+ * @return the array class
+ */
+ public static Class getArrayClass(Class clazz) {
+ Class arrayClass = null;
+ switch (clazz.getName()) {
+ case "java.lang.Byte":
+ arrayClass = Byte[].class;
+ break;
+ case "java.lang.Short":
+ arrayClass = Short[].class;
+ break;
+ case "java.lang.Integer":
+ arrayClass = Integer[].class;
+ break;
+ case "java.lang.Long":
+ arrayClass = Long[].class;
+ break;
+ case "java.lang.Float":
+ arrayClass = Float[].class;
+ break;
+ case "java.lang.Double":
+ arrayClass = Double[].class;
+ break;
+ case "java.lang.Boolean":
+ arrayClass = Boolean[].class;
+ break;
+ case "java.lang.Character":
+ arrayClass = Character[].class;
+ break;
+ case "java.lang.String":
+ arrayClass = String[].class;
+ break;
+ default:
+ }
+ return arrayClass;
+ }
+
+ /**
+ * Get t.
+ *
+ * @return the t
+ */
+ public T get() {
+ Object toReturn = configuration
+ .get(tenant, namespace, key, clazz, Hint.LATEST_LOOKUP, Hint.EXTERNAL_LOOKUP,
+ Hint.NODE_SPECIFIC);
+ if (toReturn != null && toReturn.getClass().isArray()) {
+ toReturn = Arrays.asList((Object[]) toReturn);
+ }
+ return toReturn == null ? defaultValue : (T) toReturn;
+ }
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/Hint.java b/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/Hint.java
new file mode 100644
index 0000000000..17b58f6b0e
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-api/src/main/java/org/onap/config/api/Hint.java
@@ -0,0 +1,18 @@
+package org.onap.config.api;
+
+public enum Hint {
+
+ DEFAULT(0b0), LATEST_LOOKUP(0b1), EXTERNAL_LOOKUP(0b10), NODE_SPECIFIC(0b100);
+
+ private final int lookupHint;
+
+ private Hint(int hnt) {
+ lookupHint = hnt;
+ }
+
+ public int value() {
+ return lookupHint;
+ }
+
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-cli/pom.xml b/common/onap-common-configuration-management/onap-configuration-management-cli/pom.xml
new file mode 100644
index 0000000000..f242fcc5d9
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-cli/pom.xml
@@ -0,0 +1,55 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.onap.sdc.common</groupId>
+ <name>onap-configuration-management-cli</name>
+ <artifactId>onap-configuration-management-cli</artifactId>
+
+ <parent>
+ <artifactId>onap-common-configuration-management</artifactId>
+ <groupId>org.onap.sdc.common</groupId>
+ <version>1.2.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.sdc.common</groupId>
+ <artifactId>onap-configuration-management-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>tools</groupId>
+ <artifactId>tools</artifactId>
+ <version>1.8</version>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>1.5</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <transformers>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>org.onap.config.gui.app.Configuration</mainClass>
+ </transformer>
+ </transformers>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/common/onap-common-configuration-management/onap-configuration-management-cli/src/main/java/org/onap/config/cli/app/Configuration.java b/common/onap-common-configuration-management/onap-configuration-management-cli/src/main/java/org/onap/config/cli/app/Configuration.java
new file mode 100644
index 0000000000..d1a93f0041
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-cli/src/main/java/org/onap/config/cli/app/Configuration.java
@@ -0,0 +1,119 @@
+package org.onap.config.cli.app;
+
+import org.onap.config.api.ConfigurationChangeListener;
+import org.onap.config.api.ConfigurationManager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.management.JMX;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+
+/**
+ * The type Configuration.
+ */
+public class Configuration {
+
+ /**
+ * The entry point of application.
+ *
+ * @param args the input arguments
+ * @throws Exception the exception
+ */
+ public static void main(String[] args) throws Exception {
+
+ String host = getValueFor("host", args);
+ String port = getValueFor("port", args);
+
+ if (host == null) {
+ host = "127.0.0.1";
+ }
+ if (port == null) {
+ port = "9999";
+ }
+ JMXServiceURL url =
+ new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi");
+ Map<String, String[]> env = new HashMap<>();
+ //populate dummy value. need to be changed as per impl.
+ String[] credentials = {"principal", "password"};
+ env.put(JMXConnector.CREDENTIALS, credentials);
+
+ try (JMXConnector jmxc = JMXConnectorFactory.connect(url, env)) {
+
+ boolean isUpdate = isKeyPresent("update", args);
+
+ Map<String, Object> input = new HashMap<>();
+ input.put("ImplClass", isUpdate ? "org.onap.config.type.ConfigurationUpdate"
+ : "org.onap.config.type.ConfigurationQuery");
+ input.put("externalLookup", isKeyPresent("lookup", args));
+ input.put("nodeOverride", isKeyPresent("nodeOverride", args));
+ input.put("nodeSpecific", isKeyPresent("nodeSpecific", args));
+ input.put("fallback", isKeyPresent("fallback", args));
+ input.put("latest", isKeyPresent("latest", args));
+ input.put("tenant", getValueFor("tenant", args));
+ input.put("namespace", getValueFor("namespace", args));
+ input.put("key", getValueFor("key", args));
+ input.put("value", getValueFor("value", args));
+
+
+ if (!isKeyPresent("list", args) && getValueFor("key", args) == null) {
+ throw new RuntimeException("Key is missing.");
+ }
+ if (isKeyPresent("update", args) && getValueFor("value", args) == null) {
+ throw new RuntimeException("Value is missing.");
+ }
+
+
+ MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
+ ObjectName mbeanName = new ObjectName("org.openecomp.jmx:name=SystemConfig");
+ org.onap.config.api.ConfigurationManager conf =
+ JMX.newMBeanProxy(mbsc, mbeanName, org.onap.config.api.ConfigurationManager.class,
+ true);
+
+ boolean isGet = isKeyPresent("get", args);
+ boolean isList = isKeyPresent("list", args);
+ if (isGet) {
+ System.out.println(conf.getConfigurationValue(input));
+ } else if (isList) {
+ Map<String, String> map = conf.listConfiguration(input);
+ for (Map.Entry<String, String> entry : map.entrySet()) {
+ System.out.println(entry.getKey() + " : " + entry.getValue());
+ }
+ } else if (isUpdate) {
+ conf.updateConfigurationValue(input);
+ }
+ }
+ }
+
+ private static boolean isSwitch(String key) {
+ return key.startsWith("-");
+ }
+
+ private static String getValueFor(String key, String[] args) {
+ for (int i = 0; i < args.length; i++) {
+ if (isSwitch(args[i])) {
+ String node = args[i].substring(1);
+ if (node.equalsIgnoreCase(key) && i < args.length - 1) {
+ return args[i + 1].trim().length() == 0 ? null : args[i + 1].trim();
+ }
+ }
+ }
+ return null;
+ }
+
+ private static boolean isKeyPresent(String key, String[] args) {
+ for (int i = 0; i < args.length; i++) {
+ if (isSwitch(args[i])) {
+ String node = args[i].substring(1);
+ if (node.equalsIgnoreCase(key)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-cli/src/main/java/org/onap/config/gui/app/Configuration.java b/common/onap-common-configuration-management/onap-configuration-management-cli/src/main/java/org/onap/config/gui/app/Configuration.java
new file mode 100644
index 0000000000..fa7cf5b77a
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-cli/src/main/java/org/onap/config/gui/app/Configuration.java
@@ -0,0 +1,623 @@
+package org.onap.config.gui.app;
+
+
+import com.sun.tools.attach.VirtualMachine;
+import com.sun.tools.attach.VirtualMachineDescriptor;
+import org.onap.config.api.ConfigurationManager;
+
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.CardLayout;
+import java.awt.Checkbox;
+import java.awt.CheckboxGroup;
+import java.awt.Choice;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.GridLayout;
+import java.awt.Label;
+import java.awt.Panel;
+import java.awt.ScrollPane;
+import java.awt.TextArea;
+import java.awt.TextField;
+import java.awt.Toolkit;
+import java.awt.event.ItemEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import javax.management.JMX;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+
+
+/**
+ * The type Configuration.
+ */
+public class Configuration extends Frame {
+
+ /**
+ * The Vm.
+ */
+ VirtualMachine vm = null;
+ private TextField host;
+ private TextField port;
+ private TextField user;
+ private Choice pid;
+ private TextField password;
+ private CheckboxGroup getUpdateList;
+ private CheckboxGroup localRemote;
+ private Choice tenantChoice;
+ private Choice namespaceChoice;
+ private Choice keyChoice;
+ private Checkbox latest;
+ private Checkbox lookup;
+ private Checkbox fallback;
+ private Checkbox nodeSpecific;
+ private Checkbox nodeSpecificForList;
+ private Checkbox latestForList;
+ private Checkbox lookupForList;
+ private Checkbox fallbackForList;
+ private Checkbox nodeOverride;
+ private TextArea getValue = new TextArea(1, 50);
+ private TextArea updateValue = new TextArea(1, 50);
+ private Panel table;
+ private CardLayout cards;
+ private Panel cardPanel;
+ private JMXConnector connector;
+ private ConfigurationManager manager;
+ private Frame container;
+ private Button getKeysButton;
+
+ /**
+ * Instantiates a new Configuration.
+ *
+ * @param title the title
+ */
+ public Configuration(String title) {
+ super(title);
+ setSize(300, 300);
+ setLayout(new GridLayout(2, 1));
+ Panel firstRowPanel = new Panel();
+ firstRowPanel.setLayout(new GridLayout(0, 1));
+ firstRowPanel.add(
+ buildHostPortPanel(host = new TextField("127.0.0.1"), port = new TextField("9999"),
+ pid = new Choice(), localRemote = new CheckboxGroup()));
+ firstRowPanel
+ .add(buildUserPasswordPanel(user = new TextField(""), password = new TextField("")));
+ firstRowPanel.add(buildGetUpdatelistPanel(getUpdateList = new CheckboxGroup()));
+ firstRowPanel.add(
+ buildTenantNamespacePanel(tenantChoice = new Choice(), namespaceChoice = new Choice()));
+ firstRowPanel.add(buildKeyPanel(keyChoice = new Choice()));
+ add(firstRowPanel);
+ add(cardPanel = buildCards(cards = new CardLayout()));
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent windowEvent) {
+ close();
+ System.exit(0);
+ }
+ });
+ pack();
+ setVisible(true);
+ container = this;
+ centreWindow(this);
+ Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(() -> {
+ this.populateAvailablePids();
+ validate();
+ }, 30, 30, TimeUnit.SECONDS);
+ }
+
+ /**
+ * The entry point of application.
+ *
+ * @param args the input arguments
+ */
+ public static void main(String[] args) {
+ Configuration configuration = new Configuration("Configuration Management App");
+
+ }
+
+ private void toggleLocalRemote(ItemEvent ie) {
+ if (ie.getStateChange() == ItemEvent.SELECTED) {
+ String usecase = (ie.getSource() instanceof Checkbox) ? ((Checkbox) ie.getSource()).getLabel()
+ : ((Checkbox) ie.getItem()).getLabel();
+ pid.setEnabled(usecase.equals("Local"));
+ host.setEnabled(!usecase.equals("Local"));
+ port.setEnabled(!usecase.equals("Local"));
+ }
+ }
+
+ private Panel buildHostPortPanel(TextField host, TextField port, Choice pid,
+ CheckboxGroup group) {
+ populateAvailablePids();
+ Panel panel = new Panel();
+ panel.setLayout(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 0;
+ Checkbox checkbox = null;
+ panel.add(checkbox = new Checkbox("Local", group, pid.getItemCount() > 0), gbc);
+ checkbox.addItemListener(this::toggleLocalRemote);
+ gbc.weightx = 0;
+ panel.add(checkbox = new Checkbox("Remote", group, pid.getItemCount() == 0), gbc);
+ checkbox.addItemListener(this::toggleLocalRemote);
+ gbc.weightx = 0;
+ panel.add(new Label("PID:"), gbc);
+ gbc.weightx = 1;
+ panel.add(pid, gbc);
+ gbc.weightx = 0;
+ panel.add(new Label("Host:"), gbc);
+ gbc.weightx = 1;
+ panel.add(host, gbc);
+ gbc.weightx = 0;
+ panel.add(new Label("Port:"), gbc);
+ gbc.weightx = 1;
+ panel.add(port, gbc);
+ host.setEnabled(pid.getItemCount() == 0);
+ port.setEnabled(pid.getItemCount() == 0);
+ pid.setEnabled(pid.getItemCount() > 0);
+ return panel;
+ }
+
+ private Panel buildUserPasswordPanel(TextField user, TextField password) {
+ Panel panel = new Panel();
+ password.setEchoChar('*');
+ panel.setLayout(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 0;
+ panel.add(new Label("User : "), gbc);
+ gbc.weightx = 1;
+ panel.add(user, gbc);
+ gbc.weightx = 0;
+ panel.add(new Label("Password : "), gbc);
+ gbc.weightx = 1;
+ panel.add(password, gbc);
+ gbc.weightx = 0;
+ Button button = null;
+ panel.add(button = new Button("Connect"), gbc);
+ button.addActionListener((actionListener) -> connect());
+ return panel;
+ }
+
+ /**
+ * Build get updatelist panel panel.
+ *
+ * @param getUpdtaeList the get updtae list
+ * @return the panel
+ */
+ public Panel buildGetUpdatelistPanel(CheckboxGroup getUpdtaeList) {
+ Panel panel = new Panel();
+ Checkbox checkbox = null;
+ panel.setLayout(new GridLayout(1, 3));
+ panel.add(checkbox = new Checkbox("Get", getUpdtaeList, true));
+ checkbox.addItemListener(this::showCard);
+ panel.add(checkbox = new Checkbox("List", getUpdtaeList, false));
+ checkbox.addItemListener(this::showCard);
+ panel.add(checkbox = new Checkbox("Update", getUpdtaeList, false));
+ checkbox.addItemListener(this::showCard);
+ return panel;
+ }
+
+ /**
+ * Build tenant namespace panel panel.
+ *
+ * @param tenant the tenant
+ * @param namespace the namespace
+ * @return the panel
+ */
+ public Panel buildTenantNamespacePanel(Choice tenant, Choice namespace) {
+ Panel panel = new Panel();
+ panel.setLayout(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 0;
+ panel.add(new Label("Tenant"), gbc);
+ gbc.weightx = 1;
+ panel.add(tenant, gbc);
+ gbc.weightx = 0;
+ panel.add(new Label("Namespace"), gbc);
+ gbc.weightx = 1;
+ panel.add(namespace, gbc);
+ gbc.weightx = 0;
+ panel.add(getKeysButton = new Button("Get Keys"), gbc);
+ getKeysButton.addActionListener((actionListener) -> populateKeys(
+ manager.getKeys(tenantChoice.getSelectedItem(), namespaceChoice.getSelectedItem())));
+ tenantChoice.addItemListener((itemListener) -> keyChoice.removeAll());
+ namespaceChoice.addItemListener((itemListener) -> keyChoice.removeAll());
+ return panel;
+ }
+
+ private Panel buildConnectPanel() {
+ Button button = null;
+ Panel panel = new Panel();
+ panel.setLayout(new GridLayout(1, 3));
+ panel.add(new Label());
+ panel.add(button = new Button("Connect"));
+ panel.add(new Label());
+ button.addActionListener((actionListener) -> connect());
+ return panel;
+ }
+
+ /**
+ * Build key panel panel.
+ *
+ * @param keyChoice the key choice
+ * @return the panel
+ */
+ public Panel buildKeyPanel(Choice keyChoice) {
+ Panel panel = new Panel();
+ panel.setLayout(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 0;
+ panel.add(new Label("Keys : "), gbc);
+ gbc.weightx = 1;
+ panel.add(keyChoice, gbc);
+ return panel;
+ }
+
+ /**
+ * Build cards panel.
+ *
+ * @param cards the cards
+ * @return the panel
+ */
+ public Panel buildCards(CardLayout cards) {
+ Panel panel = new Panel();
+ panel.setLayout(cards);
+ panel.add(buildCardGetPanel(latest = new Checkbox("Latest"),
+ fallback = new Checkbox("Fallback"),
+ lookup = new Checkbox("External Lookup"), nodeSpecific = new Checkbox("Node Specific"),
+ getValue), "Get");
+ panel.add(buildCardUpdatePanel(nodeOverride = new Checkbox("NodeOverride"),
+ updateValue), "Update");
+ panel.add(buildCardListPanel(table = new Panel(), latestForList = new Checkbox("Latest"),
+ fallbackForList = new Checkbox("Fallback"), lookupForList = new Checkbox("External Lookup"),
+ nodeSpecificForList = new Checkbox("Node Specific")), "List");
+ return panel;
+ }
+
+ /**
+ * Build card get panel panel.
+ *
+ * @param latest the latest
+ * @param fallback the fallback
+ * @param lookup the lookup
+ * @param nodeSpecific the node specific
+ * @param value the value
+ * @return the panel
+ */
+ public Panel buildCardGetPanel(Checkbox latest, Checkbox fallback, Checkbox lookup,
+ Checkbox nodeSpecific, TextArea value) {
+ Panel panel = new Panel();
+
+ panel.setLayout(new BorderLayout());
+ Panel p1 = new Panel();
+ p1.setLayout(new GridLayout(1, 4));
+ p1.add(latest);
+ p1.add(fallback);
+ p1.add(nodeSpecific);
+ p1.add(lookup);
+ panel.add(p1, BorderLayout.NORTH);
+ panel.add(value, BorderLayout.CENTER);
+ Panel bottom = new Panel();
+ bottom.setLayout(new GridLayout(1, 5));
+ bottom.add(new Label());
+ Button button = null;
+ bottom.add(button = new Button("GET"));
+ button.addActionListener((actionListener) -> value.setText(manager
+ .getConfigurationValue(buildMap("org.onap.config.type.ConfigurationQuery", value))));
+ bottom.add(new Label());
+ bottom.add(button = new Button("CLOSE"));
+ bottom.add(new Label());
+ panel.add(bottom, BorderLayout.SOUTH);
+ button.addActionListener((actionListener) -> {
+ close();
+ System.exit(0);
+ });
+ return panel;
+ }
+
+ private Map<String, Object> buildMap(String implClass, TextArea value) {
+ Map<String, Object> input = new HashMap<>();
+ input.put("ImplClass", implClass);//:);
+ input.put("externalLookup", value != null ? lookup.getState() : lookupForList.getState());
+ input.put("nodeOverride", nodeOverride.getState());
+ input.put("latest", value != null ? latest.getState() : latestForList.getState());
+ input.put("fallback", value != null ? fallback.getState() : fallbackForList.getState());
+ input.put("nodeSpecific",
+ value != null ? nodeSpecific.getState() : nodeSpecificForList.getState());
+ input.put("tenant", tenantChoice.getSelectedItem());
+ input.put("namespace", namespaceChoice.getSelectedItem());
+ if (keyChoice.getItemCount() == 0) {
+ message("Error", "Key is missing.");
+ throw new RuntimeException("Error");
+ }
+ input.put("key", keyChoice.getSelectedItem());
+ input.put("value", value == null ? "" : value.getText());
+ return input;
+ }
+
+ /**
+ * Build card update panel panel.
+ *
+ * @param nodeOverride the node override
+ * @param value the value
+ * @return the panel
+ */
+ public Panel buildCardUpdatePanel(Checkbox nodeOverride, TextArea value) {
+ Panel panel = new Panel();
+ panel.setLayout(new BorderLayout());
+ Panel p1 = new Panel();
+ p1.setLayout(new GridLayout(1, 1));
+ p1.add(nodeOverride);
+ panel.add(p1, BorderLayout.NORTH);
+ panel.add(value, BorderLayout.CENTER);
+ Panel bottom = new Panel();
+ bottom.setLayout(new GridLayout(1, 5));
+ bottom.add(new Label());
+ Button button = null;
+ bottom.add(button = new Button("UPDATE"));
+ button.addActionListener((actionListener) -> {
+ manager
+ .updateConfigurationValue(buildMap("org.onap.config.type.ConfigurationUpdate", value));
+ message("Info", "Success");
+ });
+ bottom.add(new Label());
+ bottom.add(button = new Button("CLOSE"));
+ bottom.add(new Label());
+ panel.add(bottom, BorderLayout.SOUTH);
+ button.addActionListener((actionListener) -> {
+ close();
+ System.exit(0);
+ });
+ return panel;
+ }
+
+ /**
+ * Build card list panel panel.
+ *
+ * @param table the table
+ * @param latest the latest
+ * @param fallback the fallback
+ * @param nodeSpecific the node specific
+ * @param lookup the lookup
+ * @return the panel
+ */
+ public Panel buildCardListPanel(Panel table, Checkbox latest, Checkbox fallback,
+ Checkbox nodeSpecific, Checkbox lookup) {
+ Panel panel = new Panel();
+ panel.setLayout(new BorderLayout());
+ table.setLayout(new GridLayout(0, 2));
+ ScrollPane sp = new ScrollPane();
+ sp.add(table);
+ panel.add(sp, BorderLayout.CENTER);
+ Panel p1 = new Panel();
+ p1.setLayout(new GridLayout(1, 4));
+ p1.add(latest);
+ p1.add(fallback);
+ p1.add(lookup);
+ p1.add(nodeSpecific);
+ panel.add(p1, BorderLayout.NORTH);
+ Panel bottom = new Panel();
+ bottom.setLayout(new GridLayout(1, 5));
+ bottom.add(new Label());
+ Button button = null;
+ bottom.add(button = new Button("List"));
+ button.addActionListener((actionListener) -> populateKeyValue(
+ manager.listConfiguration(buildMap("org.onap.config.type.ConfigurationQuery", null))));
+ bottom.add(new Label());
+ bottom.add(button = new Button("CLOSE"));
+ bottom.add(new Label());
+ panel.add(bottom, BorderLayout.SOUTH);
+ button.addActionListener((actionListener) -> {
+ close();
+ System.exit(0);
+ });
+ return panel;
+ }
+
+ private void populateKeyValue(Map<String, String> collection) {
+ table.removeAll();
+ Set<String> keys = collection.keySet();
+ for (String key : keys) {
+ table.add(new Label(key));
+ table.add(new Label(collection.get(key)));
+ }
+ table.validate();
+ }
+
+ private void showCard(ItemEvent ie) {
+ if (ie.getStateChange() == ItemEvent.SELECTED) {
+ String usecase = (ie.getSource() instanceof Checkbox) ? ((Checkbox) ie.getSource()).getLabel()
+ : ((Checkbox) ie.getItem()).getLabel();
+ cards.show(cardPanel, usecase);
+ if (usecase.equals("List")) {
+ keyChoice.removeAll();
+ }
+ keyChoice.setEnabled(!usecase.equals("List"));
+ getKeysButton.setEnabled(!usecase.equals("List"));
+ }
+ }
+
+ private void close() {
+ try {
+ if (connector != null) {
+ connector.close();
+ connector = null;
+ vm.detach();
+ }
+ } catch (Exception exception) {
+ //Do nothing
+ }
+ }
+
+ private void connect() {
+ try {
+ close();
+ if (!validateHostPort()) {
+ return;
+ }
+ JMXServiceURL url = null;
+ if (localRemote.getSelectedCheckbox().getLabel().equals("Local")) {
+ url = new JMXServiceURL(
+ (vm = VirtualMachine.attach(pid.getSelectedItem())).getAgentProperties()
+ .getProperty("com.sun.management.jmxremote.localConnectorAddress"));
+ } else {
+ url = new JMXServiceURL(
+ "service:jmx:rmi:///jndi/rmi://" + host.getText() + ":" + port.getText() + "/jmxrmi");
+ }
+ Map<String, String[]> env = new HashMap<>();
+ String[] credentials = {user.getText(), password.getText()};
+ env.put(JMXConnector.CREDENTIALS, credentials);
+ connector = JMXConnectorFactory.connect(url, env);
+ MBeanServerConnection mbsc = connector.getMBeanServerConnection();
+ ObjectName mbeanName = new ObjectName("org.openecomp.jmx:name=SystemConfig");
+ manager = JMX.newMBeanProxy(mbsc, mbeanName, ConfigurationManager.class, true);
+ message("Message", "Success!!!");
+ populateTenants(manager.getTenants());
+ populateNamespaces(manager.getNamespaces());
+ } catch (Exception exception) {
+ message("Error", exception.getMessage());
+ }
+ }
+
+ private boolean validateHostPort() {
+ if (localRemote.getSelectedCheckbox().getLabel().equals("Local")) {
+ if (pid.getSelectedItem() == null || pid.getSelectedItem().trim().length() == 0
+ || !pid.getSelectedItem().matches("^[1-9][0-9]*$")) {
+ message("Error", "pid is mandatory numeric value greater than 0.");
+ return false;
+ }
+ } else {
+ if (host.getText() == null || host.getText().trim().length() == 0) {
+ message("Error", "Host is mandatory.");
+ return false;
+ }
+ if (port.getText() == null || port.getText().trim().length() == 0
+ || !port.getText().matches("^[1-9][0-9]*$")) {
+ message("Error", "Port is mandatory numeric value greater than 0.");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void populateTenants(Collection<String> collection) {
+ tenantChoice.removeAll();
+ for (String item : collection) {
+ tenantChoice.add(item);
+ }
+ }
+
+ private void populateNamespaces(Collection<String> collection) {
+ namespaceChoice.removeAll();
+ keyChoice.removeAll();
+ for (String item : collection) {
+ namespaceChoice.add(item);
+ }
+ }
+
+ private void populateKeys(Collection<String> collection) {
+ keyChoice.removeAll();
+ for (String item : collection) {
+ keyChoice.add(item);
+ }
+ }
+
+ private void message(String title, String text) {
+ Dialog dialog = new Dialog(container, title, true);
+ dialog.setLayout(new BorderLayout());
+ dialog.add(new Label(text), BorderLayout.CENTER);
+ Button ok = new Button("OK");
+ Panel panel = new Panel();
+ panel.setLayout(new GridLayout(1, 3));
+ panel.add(new Label());
+ panel.add(ok);
+ panel.add(new Label());
+ ok.addActionListener((actionListener) -> dialog.setVisible(false));
+ dialog.add(panel, BorderLayout.SOUTH);
+ dialog.pack();
+ centerDialog(dialog);
+ dialog.setVisible(true);
+ }
+
+ private void centreWindow(Frame frame) {
+ Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
+ int x1 = (int) ((dimension.getWidth() - frame.getWidth()) / 2);
+ int y1 = (int) ((dimension.getHeight() - frame.getHeight()) / 2);
+ frame.setLocation(x1, y1);
+ }
+
+ private void centerDialog(Dialog dialog) {
+ Dimension dimension = container.getSize();
+ container.getLocationOnScreen();
+ int x1 =
+ container.getLocationOnScreen().x + (int) ((dimension.getWidth() - dialog.getWidth()) / 2);
+ int y1 = container.getLocationOnScreen().y
+ + (int) ((dimension.getHeight() - dialog.getHeight()) / 2);
+ dialog.setLocation(x1, y1);
+ }
+
+ private void setWindowPosition(Frame window, int screen) {
+ GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ GraphicsDevice[] allDevices = env.getScreenDevices();
+ int topLeftX;
+ int topLeftY;
+ int screenX;
+ int screenY;
+ int windowPosX;
+ int windowPosY;
+
+ if (screen < allDevices.length && screen > -1) {
+ topLeftX = allDevices[screen].getDefaultConfiguration().getBounds().x;
+ topLeftY = allDevices[screen].getDefaultConfiguration().getBounds().y;
+
+ screenX = allDevices[screen].getDefaultConfiguration().getBounds().width;
+ screenY = allDevices[screen].getDefaultConfiguration().getBounds().height;
+ } else {
+ topLeftX = allDevices[0].getDefaultConfiguration().getBounds().x;
+ topLeftY = allDevices[0].getDefaultConfiguration().getBounds().y;
+
+ screenX = allDevices[0].getDefaultConfiguration().getBounds().width;
+ screenY = allDevices[0].getDefaultConfiguration().getBounds().height;
+ }
+
+ windowPosX = ((screenX - window.getWidth()) / 2) + topLeftX;
+ windowPosY = ((screenY - window.getHeight()) / 2) + topLeftY;
+
+ window.setLocation(windowPosX, windowPosY);
+ }
+
+ private void populateAvailablePids() {
+ pid.removeAll();
+ for (VirtualMachineDescriptor desc : VirtualMachine.list()) {
+ try {
+ VirtualMachine vm = null;
+ JMXServiceURL url = new JMXServiceURL(
+ (vm = VirtualMachine.attach(desc.id())).getAgentProperties()
+ .getProperty("com.sun.management.jmxremote.localConnectorAddress"));
+ Set set = JMXConnectorFactory.connect(url, null).getMBeanServerConnection()
+ .queryMBeans(new ObjectName("org.openecomp.jmx:name=SystemConfig"), null);
+ if (!set.isEmpty()) {
+ pid.add(desc.id());
+ }
+ vm.detach();
+ } catch (Exception exception) {
+ //do nothing
+ }
+ }
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/pom.xml b/common/onap-common-configuration-management/onap-configuration-management-core/pom.xml
new file mode 100644
index 0000000000..70459a63a5
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/pom.xml
@@ -0,0 +1,128 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <name>onap-configuration-management-core</name>
+ <groupId>org.onap.sdc.common</groupId>
+ <artifactId>onap-configuration-management-core</artifactId>
+
+ <parent>
+ <artifactId>onap-common-configuration-management</artifactId>
+ <groupId>org.onap.sdc.common</groupId>
+ <version>1.2.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>2.5.4</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-yaml</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-configuration2</artifactId>
+ <version>2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-beanutils</groupId>
+ <artifactId>commons-beanutils</artifactId>
+ <version>${commons.beanutils.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.3.2</version>
+ </dependency>
+ <dependency>
+ <groupId>com.github.adejanovski</groupId>
+ <artifactId>cassandra-jdbc-wrapper</artifactId>
+ <version>${cassandra.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-dbcp2</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-pool2</artifactId>
+ <version>2.4.2</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>${commons.io.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.corn</groupId>
+ <artifactId>corn-cps</artifactId>
+ <version>1.1.7</version>
+ <exclusions>
+ <exclusion>
+ <groupId>com.sun</groupId>
+ <artifactId>tools</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.virtlink.commons</groupId>
+ <artifactId>commons-configuration2-jackson</artifactId>
+ <version>0.6.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>2.7</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-ext</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.sdc.common</groupId>
+ <artifactId>onap-configuration-management-api</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <version>3.1.0</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>2.8.1</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ <version>${junit.version}</version>
+ </dependency>
+
+ </dependencies>
+
+</project>
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/ConfigurationUtils.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/ConfigurationUtils.java
new file mode 100644
index 0000000000..7f22461cda
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/ConfigurationUtils.java
@@ -0,0 +1,1144 @@
+package org.onap.config;
+
+import com.google.common.collect.ImmutableMap;
+import com.virtlink.commons.configuration2.jackson.JsonConfiguration;
+import net.sf.corn.cps.CPScanner;
+import net.sf.corn.cps.ResourceFilter;
+import org.apache.commons.configuration2.CompositeConfiguration;
+import org.apache.commons.configuration2.Configuration;
+import org.apache.commons.configuration2.FileBasedConfiguration;
+import org.apache.commons.configuration2.PropertiesConfiguration;
+import org.apache.commons.configuration2.XMLConfiguration;
+import org.apache.commons.configuration2.builder.BasicConfigurationBuilder;
+import org.apache.commons.configuration2.builder.ReloadingFileBasedConfigurationBuilder;
+import org.apache.commons.configuration2.builder.fluent.Configurations;
+import org.apache.commons.configuration2.builder.fluent.Parameters;
+import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
+import org.apache.commons.configuration2.ex.ConfigurationException;
+import org.apache.commons.io.IOUtils;
+import org.onap.config.api.Config;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.impl.ConfigurationRepository;
+import org.onap.config.impl.YamlConfiguration;
+import org.onap.config.impl.AgglomerateConfiguration;
+import org.onap.config.impl.ConfigurationDataSource;
+import org.onap.config.type.ConfigurationMode;
+import org.onap.config.type.ConfigurationType;
+
+import javax.sql.DataSource;
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.LinkedTransferQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TransferQueue;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static com.google.common.collect.ImmutableMap.builder;
+import static org.onap.config.api.Hint.EXTERNAL_LOOKUP;
+import static org.onap.config.api.Hint.LATEST_LOOKUP;
+import static org.onap.config.api.Hint.NODE_SPECIFIC;
+
+/**
+ * The type Configuration utils.
+ */
+public class ConfigurationUtils {
+
+ private ConfigurationUtils() {
+ }
+
+ private static ImmutableMap<Class,Class> arrayClassMap;
+
+ static {
+ ImmutableMap.Builder<Class,Class> builder = builder();
+ builder.put(Byte.class,Byte[].class).put(Short.class, Short[].class)
+ .put(Integer.class,Integer[].class).put(Long.class,Long[].class)
+ .put(Float.class,Float[].class).put(Double.class,Double[].class)
+ .put(Boolean.class,Boolean[].class).put(Character.class,Character[].class)
+ .put(String.class,String[].class);
+ arrayClassMap = builder.build();
+ }
+
+ /**
+ * Gets thread factory.
+ *
+ * @return the thread factory
+ */
+ public static ThreadFactory getThreadFactory() {
+ return (r1) -> {
+ Thread thread = Executors.privilegedThreadFactory().newThread(r1);
+ thread.setDaemon(true);
+ return thread;
+ };
+ }
+
+ /**
+ * Gets all files.
+ *
+ * @param file the file
+ * @param recursive the recursive
+ * @param onlyDirectory the only directory
+ * @return the all files
+ */
+ public static Collection<File> getAllFiles(File file, boolean recursive, boolean onlyDirectory) {
+ ArrayList<File> collection = new ArrayList<>();
+ if (file.isDirectory() && file.exists()) {
+ File[] files = file.listFiles();
+ for (File innerFile : files) {
+ if (innerFile.isFile() && !onlyDirectory) {
+ collection.add(innerFile);
+ } else if (innerFile.isDirectory()) {
+ collection.add(innerFile);
+ if (recursive) {
+ collection.addAll(getAllFiles(innerFile, recursive, onlyDirectory));
+ }
+ }
+ }
+ }
+ return collection;
+ }
+
+ /**
+ * Gets comma saperated list.
+ *
+ * @param list the list
+ * @return the comma separated list
+ */
+ public static String getCommaSeparatedList(List list) {
+ return ((Stream<String>) list.stream().filter(o -> o != null && !o.toString().trim().isEmpty()).map(o -> o.toString().trim())).collect(Collectors.joining(","));
+ }
+
+ /**
+ * Gets comma saperated list.
+ *
+ * @param list the list
+ * @return the comma saperated list
+ */
+ public static String getCommaSeparatedList(String[] list) {
+ return getCommaSeparatedList(list == null ? Arrays.asList() : Arrays.asList(list));
+ }
+
+ /**
+ * Gets config type.
+ *
+ * @param url the url
+ * @return the config type
+ */
+ public static ConfigurationType getConfigType(URL url) {
+ return Enum.valueOf(ConfigurationType.class,
+ url.getFile().substring(url.getFile().lastIndexOf('.') + 1).toUpperCase());
+ }
+
+ /**
+ * Gets config type.
+ *
+ * @param file the file
+ * @return the config type
+ */
+ public static ConfigurationType getConfigType(File file) {
+ return Enum.valueOf(ConfigurationType.class,
+ file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf('.') + 1)
+ .toUpperCase());
+ }
+
+ /**
+ * Is config boolean.
+ *
+ * @param url the url
+ * @return the boolean
+ */
+ public static boolean isConfig(URL url) {
+ return isConfig(url.getFile());
+ }
+
+ /**
+ * Is config boolean.
+ *
+ * @param file the file
+ * @return the boolean
+ */
+ public static boolean isConfig(File file) {
+ return file != null && file.exists() && isConfig(file.getName());
+ }
+
+ /**
+ * Is config boolean.
+ *
+ * @param file the file
+ * @return the boolean
+ */
+ public static boolean isConfig(String file) {
+ file = file.toUpperCase().substring(file.lastIndexOf('!') + 1);
+ file = file.substring(file.lastIndexOf('/') + 1);
+ return file.matches(
+ "CONFIG(-\\w*){0,1}(-" + "(" + ConfigurationMode.OVERRIDE + "|" + ConfigurationMode.MERGE
+ + "|" + ConfigurationMode.UNION + ")){0,1}" + "\\.("
+ + ConfigurationType.PROPERTIES.name() + "|" + ConfigurationType.XML.name() + "|"
+ + ConfigurationType.JSON.name() + "|" + ConfigurationType.YAML.name() + ")$")
+ || file.matches("CONFIG(.)*\\.(" + ConfigurationType.PROPERTIES.name() + "|"
+ + ConfigurationType.XML.name() + "|" + ConfigurationType.JSON.name() + "|"
+ + ConfigurationType.YAML.name() + ")$");
+ }
+
+ /**
+ * Gets namespace.
+ *
+ * @param url the url
+ * @return the namespace
+ */
+ public static String getNamespace(URL url) {
+ String namespace = getNamespace(getConfiguration(url));
+ if (namespace != null) {
+ return namespace.toUpperCase();
+ }
+ return getNamespace(url.getFile().toUpperCase());
+ }
+
+ /**
+ * Gets namespace.
+ *
+ * @param file the file
+ * @return the namespace
+ */
+ public static String getNamespace(File file) {
+ String namespace = getNamespace(getConfiguration(file));
+ if (namespace != null) {
+ return namespace.toUpperCase();
+ }
+ return getNamespace(file.getName().toUpperCase());
+ }
+
+ private static String getNamespace(Configuration config) {
+ return config.getString(Constants.NAMESPACE_KEY) == null ? null
+ : config.getString(Constants.NAMESPACE_KEY).toUpperCase();
+ }
+
+ /**
+ * Gets namespace.
+ *
+ * @param file the file
+ * @return the namespace
+ */
+ public static String getNamespace(String file) {
+ file = file.toUpperCase().substring(file.lastIndexOf('!') + 1);
+ file = file.substring(file.lastIndexOf('/') + 1);
+ Pattern pattern = Pattern.compile(
+ "CONFIG(-\\w*){0,1}(-" + "(" + ConfigurationMode.OVERRIDE + "|" + ConfigurationMode.MERGE
+ + "|" + ConfigurationMode.UNION + ")){0,1}" + "\\.("
+ + ConfigurationType.PROPERTIES.name() + "|" + ConfigurationType.XML.name() + "|"
+ + ConfigurationType.JSON.name() + "|" + ConfigurationType.YAML.name() + ")$");
+ Matcher matcher = pattern.matcher(file);
+ boolean b1 = matcher.matches();
+ if (b1) {
+ if (matcher.group(1) != null) {
+ String moduleName = matcher.group(1).substring(1);
+ return moduleName.equalsIgnoreCase(ConfigurationMode.OVERRIDE.name())
+ || moduleName.equalsIgnoreCase(ConfigurationMode.UNION.name())
+ || moduleName.equalsIgnoreCase(ConfigurationMode.MERGE.name())
+ ? Constants.DEFAULT_NAMESPACE : moduleName;
+ } else {
+ return Constants.DEFAULT_NAMESPACE;
+ }
+ } else if (isConfig(file)) {
+ return Constants.DEFAULT_NAMESPACE;
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets merge strategy.
+ *
+ * @param url the url
+ * @return the merge strategy
+ */
+ public static ConfigurationMode getMergeStrategy(URL url) {
+ String configMode = getMergeStrategy(getConfiguration(url));
+ if (configMode != null) {
+ try {
+ return Enum.valueOf(ConfigurationMode.class, configMode);
+ } catch (Exception exception) {
+ //do nothing
+ }
+ }
+ return getMergeStrategy(url.getFile().toUpperCase());
+ }
+
+ private static String getMergeStrategy(Configuration config) {
+ return config.getString(Constants.MODE_KEY) == null ? null
+ : config.getString(Constants.MODE_KEY).toUpperCase();
+ }
+
+ /**
+ * Gets merge strategy.
+ *
+ * @param file the file
+ * @return the merge strategy
+ */
+ public static ConfigurationMode getMergeStrategy(File file) {
+ String configMode = getMergeStrategy(getConfiguration(file));
+ if (configMode != null) {
+ try {
+ return Enum.valueOf(ConfigurationMode.class, configMode);
+ } catch (Exception exception) {
+ //do nothing
+ }
+ }
+ return getMergeStrategy(file.getName().toUpperCase());
+ }
+
+ /**
+ * Gets merge strategy.
+ *
+ * @param file the file
+ * @return the merge strategy
+ */
+ public static ConfigurationMode getMergeStrategy(String file) {
+ file = file.toUpperCase().substring(file.lastIndexOf('!') + 1);
+ file = file.substring(file.lastIndexOf('/') + 1);
+ Pattern pattern = Pattern.compile(
+ "CONFIG(-\\w*){0,1}(-" + "(" + ConfigurationMode.OVERRIDE + "|" + ConfigurationMode.MERGE
+ + "|" + ConfigurationMode.UNION + ")){0,1}" + "\\.("
+ + ConfigurationType.PROPERTIES.name() + "|" + ConfigurationType.XML.name() + "|"
+ + ConfigurationType.JSON.name() + "|" + ConfigurationType.YAML.name() + ")$");
+ Matcher matcher = pattern.matcher(file);
+ boolean b1 = matcher.matches();
+ if (b1) {
+ for (int i = 1; i <= matcher.groupCount(); i++) {
+ String modeName = matcher.group(i);
+ if (modeName != null) {
+ modeName = modeName.substring(1);
+ }
+ try {
+ return Enum.valueOf(ConfigurationMode.class, modeName);
+ } catch (Exception exception) {
+ //do nothing
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets configuration.
+ *
+ * @param url the url
+ * @return the configuration
+ */
+ public static FileBasedConfiguration getConfiguration(URL url) {
+ FileBasedConfiguration builder = null;
+ try {
+ ConfigurationType configType = ConfigurationUtils.getConfigType(url);
+ switch (configType) {
+ case PROPERTIES:
+ builder = new Configurations().fileBased(PropertiesConfiguration.class, url);
+ break;
+ case XML:
+ builder = new Configurations().fileBased(XMLConfiguration.class, url);
+ break;
+ case JSON:
+ builder = new Configurations().fileBased(JsonConfiguration.class, url);
+ break;
+ case YAML:
+ builder = new Configurations().fileBased(YamlConfiguration.class, url);
+ break;
+ default:
+ throw new ConfigurationException("Configuration type not supported:"+ configType);
+ }
+ } catch (ConfigurationException exception) {
+ exception.printStackTrace();
+ }
+ return builder;
+ }
+
+ /**
+ * Gets configuration.
+ *
+ * @param file the file
+ * @return the configuration
+ */
+ public static FileBasedConfiguration getConfiguration(File file) {
+ FileBasedConfiguration builder = null;
+ try {
+ ConfigurationType configType = ConfigurationUtils.getConfigType(file);
+ switch (configType) {
+ case PROPERTIES:
+ builder = new Configurations().fileBased(PropertiesConfiguration.class, file);
+ break;
+ case XML:
+ builder = new Configurations().fileBased(XMLConfiguration.class, file);
+ break;
+ case JSON:
+ builder = new Configurations().fileBased(JsonConfiguration.class, file);
+ break;
+ case YAML:
+ builder = new Configurations().fileBased(YamlConfiguration.class, file);
+ break;
+ default:
+ throw new ConfigurationException("Configuration type not supported:"+ configType);
+ }
+ } catch (ConfigurationException exception) {
+ exception.printStackTrace();
+ }
+ return builder;
+ }
+
+ /**
+ * Gets collection generic type.
+ *
+ * @param field the field
+ * @return the collection generic type
+ */
+ public static Class getCollectionGenericType(Field field) {
+ Type type = field.getGenericType();
+
+ if (type instanceof ParameterizedType) {
+
+ ParameterizedType paramType = (ParameterizedType) type;
+ Type[] arr = paramType.getActualTypeArguments();
+
+ for (Type tp : arr) {
+ Class<?> clzz = (Class<?>) tp;
+ if (isWrapperClass(clzz)) {
+ return clzz;
+ } else {
+ throw new RuntimeException("Collection of type " + clzz.getName() + " not supported.");
+ }
+ }
+ }
+ return String[].class;
+ }
+
+
+
+ /**
+ * Gets array class.
+ *
+ * @param clazz the clazz
+ * @return the array class
+ */
+ public static Class getArrayClass(Class clazz) {
+ return arrayClassMap.getOrDefault(clazz, null);
+ }
+
+ /**
+ * Gets all class path resources.
+ *
+ * @return the all class path resources
+ */
+ public static List<URL> getAllClassPathResources() {
+ return CPScanner.scanResources(new ResourceFilter());
+ }
+
+ /**
+ * Execute ddlsql boolean.
+ *
+ * @param sql the sql
+ * @return the boolean
+ * @throws Exception the exception
+ */
+ public static boolean executeDdlSql(String sql) throws Exception {
+ DataSource datasource = ConfigurationDataSource.lookup();
+ if (datasource == null) {
+ System.err.println("DB configuration not found. Configuration management will be using "
+ + "in-memory persistence.");
+ return false;
+ }
+ try (Connection con = datasource.getConnection(); Statement stmt = con.createStatement()) {
+ stmt.executeQuery(sql);
+ } catch (Exception exception) {
+ System.err.println("Datasource initialization error. Configuration management will be using in-memory persistence.");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Gets configuration builder.
+ *
+ * @param url the url
+ * @return the configuration builder
+ */
+ public static BasicConfigurationBuilder<FileBasedConfiguration> getConfigurationBuilder(URL url) {
+ ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> builder = null;
+ ConfigurationType configType = ConfigurationUtils.getConfigType(url);
+ switch (configType) {
+ case PROPERTIES:
+ builder = new ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration>(
+ PropertiesConfiguration.class);
+ break;
+ case XML:
+ builder = new ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration>(
+ XMLConfiguration.class);
+ break;
+ case JSON:
+ builder = new ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration>(
+ JsonConfiguration.class);
+ break;
+ case YAML:
+ builder = new ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration>(
+ YamlConfiguration.class);
+ break;
+ default:
+ throw new IllegalArgumentException("Configuration type not supported:"+ configType);
+ }
+ builder.configure(new Parameters().fileBased().setURL(url)
+ .setListDelimiterHandler(new DefaultListDelimiterHandler(',')));
+ return builder;
+ }
+
+ /**
+ * Gets configuration builder.
+ *
+ * @param file the file
+ * @param autoSave the auto save
+ * @return the configuration builder
+ */
+ public static BasicConfigurationBuilder<FileBasedConfiguration> getConfigurationBuilder(File file,
+ boolean autoSave) {
+ ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> builder = null;
+ ConfigurationType configType = ConfigurationUtils.getConfigType(file);
+ switch (configType) {
+ case PROPERTIES:
+ builder = new ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration>(
+ PropertiesConfiguration.class);
+ break;
+ case XML:
+ builder = new ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration>(
+ XMLConfiguration.class);
+ break;
+ case JSON:
+ builder = new ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration>(
+ JsonConfiguration.class);
+ break;
+ case YAML:
+ builder = new ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration>(
+ YamlConfiguration.class);
+ break;
+ default:
+ throw new IllegalArgumentException("Configuration type not supported:"+ configType);
+ }
+ builder.configure(new Parameters().fileBased().setFile(file)
+ .setListDelimiterHandler(new DefaultListDelimiterHandler(',')));
+ builder.setAutoSave(autoSave);
+ return builder;
+ }
+
+
+ /**
+ * Execute select sql collection.
+ *
+ * @param sql the sql
+ * @param params the params
+ * @return the collection
+ * @throws Exception the exception
+ */
+ public static Collection<String> executeSelectSql(String sql, String[] params) throws Exception {
+ Collection<String> coll = new ArrayList<>();
+ DataSource datasource = ConfigurationDataSource.lookup();
+ try (Connection con = datasource.getConnection();
+ PreparedStatement stmt = con.prepareStatement(sql)) {
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ stmt.setString(i + 1, params[i]);
+ }
+ }
+
+ try (ResultSet rs = stmt.executeQuery()) {
+
+ while (rs.next()) {
+ coll.add(rs.getString(1));
+ }
+ }
+
+ } catch (Exception exception) {
+ //exception.printStackTrace();
+ return null;
+ }
+
+ return coll;
+ }
+
+ /**
+ * Execute insert sql boolean.
+ *
+ * @param sql the sql
+ * @param params the params
+ * @return the boolean
+ * @throws Exception the exception
+ */
+ public static boolean executeInsertSql(String sql, Object[] params) throws Exception {
+ Collection<String> coll = new ArrayList<>();
+ DataSource datasource = ConfigurationDataSource.lookup();
+ try (Connection con = datasource.getConnection();
+ PreparedStatement stmt = con.prepareStatement(sql)) {
+ if (params != null) {
+ int counter = 0;
+ for (Object obj : params) {
+ if (obj == null) {
+ obj = "";
+ }
+ switch (obj.getClass().getName()) {
+ case "java.lang.String":
+ stmt.setString(++counter, obj.toString());
+ break;
+ case "java.lang.Integer":
+ stmt.setInt(++counter, ((Integer) obj).intValue());
+ break;
+ case "java.lang.Long":
+ stmt.setLong(++counter, ((Long) obj).longValue());
+ break;
+ default:
+ stmt.setString(++counter, obj.toString());
+ break;
+ }
+ }
+ }
+ stmt.executeUpdate();
+ return true;
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ return false;
+ }
+
+ /**
+ * Read t.
+ *
+ * @param <T> the type parameter
+ * @param config the config
+ * @param clazz the clazz
+ * @param keyPrefix the key prefix
+ * @return the t
+ * @throws Exception the exception
+ */
+ public static <T> T read(Configuration config, Class<T> clazz, String keyPrefix)
+ throws Exception {
+ Config confAnnot =
+ clazz.getAnnotation(Config.class);
+ if (confAnnot != null) {
+ keyPrefix += (confAnnot.key() + ".");
+ }
+ T objToReturn = clazz.newInstance();
+ for (Field field : clazz.getDeclaredFields()) {
+ Config fieldConfAnnot =
+ field.getAnnotation(Config.class);
+ if (fieldConfAnnot != null) {
+ field.setAccessible(true);
+ field.set(objToReturn, config.getProperty(keyPrefix + fieldConfAnnot.key()));
+ } else if (field.getType().getAnnotation(Config.class) != null) {
+ field.set(objToReturn, read(config, field.getType(), keyPrefix));
+ }
+ }
+ return objToReturn;
+ }
+
+ /**
+ * Gets db configuration builder.
+ *
+ * @param configName the config name
+ * @return the db configuration builder
+ * @throws Exception the exception
+ */
+ public static BasicConfigurationBuilder<AgglomerateConfiguration> getDbConfigurationBuilder(
+ String configName) throws Exception {
+ Configuration dbConfig = ConfigurationRepository.lookup()
+ .getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE);
+ BasicConfigurationBuilder<AgglomerateConfiguration> builder =
+ new BasicConfigurationBuilder<AgglomerateConfiguration>(AgglomerateConfiguration.class);
+ builder.configure(
+ new Parameters().database()
+ .setDataSource(ConfigurationDataSource.lookup())
+ .setTable(dbConfig.getString("config.Table"))
+ .setKeyColumn(dbConfig.getString("configKey"))
+ .setValueColumn(dbConfig.getString("configValue"))
+ .setConfigurationNameColumn(dbConfig.getString("configNameColumn"))
+ .setConfigurationName(configName)
+ .setAutoCommit(true)
+ );
+ return builder;
+ }
+
+ /**
+ * Gets property.
+ *
+ * @param config the config
+ * @param key the key
+ * @param processingHints the processing hints
+ * @return the property
+ */
+ public static Object getProperty(Configuration config, String key, int processingHints) {
+ if (!isDirectLookup(processingHints)) {
+ if (config instanceof AgglomerateConfiguration) {
+ return ((AgglomerateConfiguration) config).getPropertyValue(key);
+ } else if (config instanceof CompositeConfiguration) {
+ CompositeConfiguration conf = (CompositeConfiguration) config;
+ for (int i = 0; i < conf.getNumberOfConfigurations(); i++) {
+ if (conf.getConfiguration(i) instanceof AgglomerateConfiguration) {
+ return ((AgglomerateConfiguration) conf.getConfiguration(i)).getPropertyValue(key);
+ } else if (isNodeSpecific(processingHints)) {
+ Object obj = conf.getConfiguration(i).getProperty(key);
+ if (obj != null) {
+ return obj;
+ }
+ }
+ }
+ }
+ }
+ return config.getProperty(key);
+ }
+
+ /**
+ * Gets primitive array.
+ *
+ * @param collection the collection
+ * @param clazz the clazz
+ * @return the primitive array
+ */
+ public static Object getPrimitiveArray(Collection collection, Class clazz) {
+ if (clazz == int.class) {
+ int[] array = new int[collection.size()];
+ Object[] objArray = collection.toArray();
+ for (int i = 0; i < collection.size(); i++) {
+ array[i] = (int) objArray[i];
+ }
+ return array;
+ }
+ if (clazz == byte.class) {
+ byte[] array = new byte[collection.size()];
+ Object[] objArray = collection.toArray();
+ for (int i = 0; i < collection.size(); i++) {
+ array[i] = (byte) objArray[i];
+ }
+ return array;
+ }
+ if (clazz == short.class) {
+ short[] array = new short[collection.size()];
+ Object[] objArray = collection.toArray();
+ for (int i = 0; i < collection.size(); i++) {
+ array[i] = (short) objArray[i];
+ }
+ return array;
+ }
+ if (clazz == long.class) {
+ long[] array = new long[collection.size()];
+ Object[] objArray = collection.toArray();
+ for (int i = 0; i < collection.size(); i++) {
+ array[i] = (long) objArray[i];
+ }
+ return array;
+ }
+ if (clazz == float.class) {
+ float[] array = new float[collection.size()];
+ Object[] objArray = collection.toArray();
+ for (int i = 0; i < collection.size(); i++) {
+ array[i] = (float) objArray[i];
+ }
+ return array;
+ }
+ if (clazz == double.class) {
+ double[] array = new double[collection.size()];
+ Object[] objArray = collection.toArray();
+ for (int i = 0; i < collection.size(); i++) {
+ array[i] = (double) objArray[i];
+ }
+ return array;
+ }
+ if (clazz == boolean.class) {
+ boolean[] array = new boolean[collection.size()];
+ Object[] objArray = collection.toArray();
+ for (int i = 0; i < collection.size(); i++) {
+ array[i] = (boolean) objArray[i];
+ }
+ return array;
+ }
+ Object obj = null;
+ return obj;
+ }
+
+ /**
+ * Is wrapper class boolean.
+ *
+ * @param clazz the clazz
+ * @return the boolean
+ */
+ public static boolean isWrapperClass(Class clazz) {
+ return clazz == String.class || clazz == Boolean.class || clazz == Character.class
+ || Number.class.isAssignableFrom(clazz);
+ }
+
+ /**
+ * Gets collection string.
+ *
+ * @param input the input
+ * @return the collection string
+ */
+ public static String getCollectionString(String input) {
+ Pattern pattern = Pattern.compile("^\\[(.*)\\]$");
+ Matcher matcher = pattern.matcher(input);
+ if (matcher.matches()) {
+ input = matcher.group(1);
+ }
+ return input;
+ }
+
+ /**
+ * Is collection boolean.
+ *
+ * @param input the input
+ * @return the boolean
+ */
+ public static boolean isCollection(String input) {
+ Pattern pattern = Pattern.compile("^\\[(.*)\\]$");
+ Matcher matcher = pattern.matcher(input);
+ return matcher.matches();
+ }
+
+ /**
+ * Process variables if present string.
+ *
+ * @param tenant the tenant
+ * @param namespace the namespace
+ * @param data the data
+ * @return the string
+ */
+ public static String processVariablesIfPresent(String tenant, String namespace, String data) {
+ Pattern pattern = Pattern.compile("^.*\\$\\{(.*)\\}.*");
+ Matcher matcher = pattern.matcher(data);
+ if (matcher.matches()) {
+ String key = matcher.group(1);
+ if (key.toUpperCase().startsWith("ENV:")) {
+ String envValue = System.getenv(key.substring(4));
+ return processVariablesIfPresent(tenant, namespace, data.replaceAll("\\$\\{" + key + "\\}",
+ envValue == null ? "" : envValue.replace("\\", "\\\\")));
+ } else if (key.toUpperCase().startsWith("SYS:")) {
+ String sysValue = System.getProperty(key.substring(4));
+ return processVariablesIfPresent(tenant, namespace, data.replaceAll("\\$\\{" + key + "\\}",
+ sysValue == null ? "" : sysValue.replace("\\", "\\\\")));
+ } else {
+ String propertyValue = ConfigurationUtils.getCollectionString(
+ ConfigurationManager.lookup().getAsStringValues(tenant, namespace, key).toString());
+ return processVariablesIfPresent(tenant, namespace, data.replaceAll("\\$\\{" + key + "\\}",
+ propertyValue == null ? "" : propertyValue.replace("\\", "\\\\")));
+ }
+ } else {
+ return data;
+ }
+ }
+
+ /**
+ * Gets file contents.
+ *
+ * @param path the path
+ * @return the file contents
+ */
+ public static String getFileContents(String path) {
+ try {
+ if (path != null) {
+ return IOUtils.toString(new URL(path));
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Gets file contents.
+ *
+ * @param path the path
+ * @return the file contents
+ */
+ public static String getFileContents(Path path) {
+ try {
+ if (path != null) {
+ return new String(Files.readAllBytes(path));
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Gets concrete collection.
+ *
+ * @param clazz the clazz
+ * @return the concrete collection
+ */
+ public static Collection getConcreteCollection(Class clazz) {
+ switch (clazz.getName()) {
+ case "java.util.Collection":
+ case "java.util.List":
+ return new ArrayList<>();
+ case "java.util.Set":
+ return new HashSet<>();
+ case "java.util.SortedSet":
+ return new TreeSet<>();
+ case "java.util.Queue":
+ return new ConcurrentLinkedQueue<>();
+ case "java.util.Deque":
+ return new ArrayDeque<>();
+ case "java.util.concurrent.TransferQueue":
+ return new LinkedTransferQueue<>();
+ case "java.util.concurrent.BlockingQueue":
+ return new LinkedBlockingQueue<>();
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Gets default for.
+ *
+ * @param clazz the clazz
+ * @return the default for
+ */
+ public static Object getDefaultFor(Class clazz) {
+ if (byte.class == clazz) {
+ return new Byte("0");
+ } else if (short.class == clazz) {
+ return new Short("0");
+ } else if (int.class == clazz) {
+ return new Integer("0");
+ } else if (float.class == clazz) {
+ return new Float("0");
+ } else if (long.class == clazz) {
+ return new Long("0");
+ } else if (double.class == clazz) {
+ return new Double("0");
+ } else if (boolean.class == clazz) {
+ return Boolean.FALSE;
+ }
+ return new Character((char) 0);
+ }
+
+ /**
+ * Gets compatible collection for abstract def.
+ *
+ * @param clazz the clazz
+ * @return the compatible collection for abstract def
+ */
+ public static Collection getCompatibleCollectionForAbstractDef(Class clazz) {
+ if (BlockingQueue.class.isAssignableFrom(clazz)) {
+ return getConcreteCollection(BlockingQueue.class);
+ }
+ if (TransferQueue.class.isAssignableFrom(clazz)) {
+ return getConcreteCollection(TransferQueue.class);
+ }
+ if (Deque.class.isAssignableFrom(clazz)) {
+ return getConcreteCollection(Deque.class);
+ }
+ if (Queue.class.isAssignableFrom(clazz)) {
+ return getConcreteCollection(Queue.class);
+ }
+ if (SortedSet.class.isAssignableFrom(clazz)) {
+ return getConcreteCollection(SortedSet.class);
+ }
+ if (Set.class.isAssignableFrom(clazz)) {
+ return getConcreteCollection(Set.class);
+ }
+ if (List.class.isAssignableFrom(clazz)) {
+ return getConcreteCollection(List.class);
+ }
+ return null;
+ }
+
+ /**
+ * Gets configuration repository key.
+ *
+ * @param array the array
+ * @return the configuration repository key
+ */
+ public static String getConfigurationRepositoryKey(String[] array) {
+ Deque<String> stack = new ArrayDeque<>();
+ stack.push(Constants.DEFAULT_TENANT);
+ for (String element : array) {
+ stack.push(element);
+ }
+ String toReturn = stack.pop();
+ return stack.pop() + Constants.KEY_ELEMENTS_DELEMETER + toReturn;
+ }
+
+ /**
+ * Gets configuration repository key.
+ *
+ * @param file the file
+ * @return the configuration repository key
+ */
+ public static String getConfigurationRepositoryKey(File file) {
+ return getConfigurationRepositoryKey(
+ ConfigurationUtils.getNamespace(file).split(Constants.TENANT_NAMESPACE_SAPERATOR));
+ }
+
+ /**
+ * Gets configuration repository key.
+ *
+ * @param url the url
+ * @return the configuration repository key
+ */
+ public static String getConfigurationRepositoryKey(URL url) {
+ return getConfigurationRepositoryKey(
+ ConfigurationUtils.getNamespace(url).split(Constants.TENANT_NAMESPACE_SAPERATOR));
+ }
+
+ /**
+ * To map linked hash map.
+ *
+ * @param config the config
+ * @return the linked hash map
+ */
+ public static LinkedHashMap toMap(Configuration config) {
+ Iterator<String> iterator = config.getKeys();
+ LinkedHashMap<String, String> map = new LinkedHashMap<>();
+ while (iterator.hasNext()) {
+ String key = iterator.next();
+ if (!(key.equals(Constants.MODE_KEY) || key.equals(Constants.NAMESPACE_KEY)
+ || key.equals(Constants.LOAD_ORDER_KEY))) {
+ map.put(key, config.getProperty(key).toString());
+ }
+ }
+
+ return map;
+ }
+
+ /**
+ * Diff map.
+ *
+ * @param orig the orig
+ * @param latest the latest
+ * @return the map
+ */
+ public static Map diff(LinkedHashMap orig, LinkedHashMap latest) {
+ orig = new LinkedHashMap<>(orig);
+ latest = new LinkedHashMap<>(latest);
+ List<String> set = new ArrayList(orig.keySet());
+ for (String key : set) {
+ if (latest.remove(key, orig.get(key))) {
+ orig.remove(key);
+ }
+ }
+ Set<String> keys = latest.keySet();
+ for (String key : keys) {
+ orig.remove(key);
+ }
+ set = new ArrayList(orig.keySet());
+ for (String key : set) {
+ latest.put(key, "");
+ }
+ return new HashMap<>(latest);
+ }
+
+ /**
+ * Is array boolean.
+ *
+ * @param tenant the tenant
+ * @param namespace the namespace
+ * @param key the key
+ * @param processingHints the processing hints
+ * @return the boolean
+ * @throws Exception the exception
+ */
+ public static boolean isArray(String tenant, String namespace, String key, int processingHints)
+ throws Exception {
+ Object obj = ConfigurationUtils
+ .getProperty(ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace), key,
+ processingHints);
+ return (obj == null) ? false : ConfigurationUtils.isCollection(obj.toString());
+ }
+
+ /**
+ * Is direct lookup boolean.
+ *
+ * @param hints the hints
+ * @return the boolean
+ */
+ public static boolean isDirectLookup(int hints) {
+ return (hints & LATEST_LOOKUP.value()) == LATEST_LOOKUP.value();
+ }
+
+ /**
+ * Is external lookup boolean.
+ *
+ * @param hints the hints
+ * @return the boolean
+ */
+ public static boolean isExternalLookup(int hints) {
+ return (hints & EXTERNAL_LOOKUP.value()) == EXTERNAL_LOOKUP.value();
+ }
+
+ /**
+ * Is node specific boolean.
+ *
+ * @param hints the hints
+ * @return the boolean
+ */
+ public static boolean isNodeSpecific(int hints) {
+ return (hints & NODE_SPECIFIC.value()) == NODE_SPECIFIC.value();
+ }
+
+ public static boolean isZeroLengthArray(Class clazz, Object obj) {
+ if (clazz.isArray() && clazz.getComponentType().isPrimitive()) {
+ if (clazz.getComponentType() == int.class) {
+ return ((int[]) obj).length == 0;
+ } else if (clazz.getComponentType() == byte.class) {
+ return ((byte[]) obj).length == 0;
+ } else if (clazz.getComponentType() == short.class) {
+ return ((short[]) obj).length == 0;
+ } else if (clazz.getComponentType() == float.class) {
+ return ((float[]) obj).length == 0;
+ } else if (clazz.getComponentType() == boolean.class) {
+ return ((boolean[]) obj).length == 0;
+ } else if (clazz.getComponentType() == double.class) {
+ return ((double[]) obj).length == 0;
+ } else if (clazz.getComponentType() == long.class) {
+ return ((long[]) obj).length == 0;
+ } else {
+ return ((Object[]) obj).length == 0;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks if value is blank
+ *
+ * @param value
+ * @return
+ */
+ public static boolean isBlank(String value) {
+ return value == null || value.trim().length() == 0;
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/Constants.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/Constants.java
new file mode 100644
index 0000000000..a16607cbc0
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/Constants.java
@@ -0,0 +1,14 @@
+package org.onap.config;
+
+public class Constants {
+
+ public static final String DEFAULT_TENANT = "GLOBAL";
+ public static final String DEFAULT_NAMESPACE = "COMMON";
+ public static final String DB_NAMESPACE = "SYSTEM";
+ public static final String KEY_ELEMENTS_DELEMETER = "-";
+ public static final String TENANT_NAMESPACE_SAPERATOR = ":";
+ public static final String NAMESPACE_KEY = "_config.namespace";
+ public static final String MODE_KEY = "_config.mergeStrategy";
+ public static final String MBEAN_NAME = "org.openecomp.jmx:name=SystemConfig";
+ public final static String LOAD_ORDER_KEY="_config.loadOrder";
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/NonConfigResource.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/NonConfigResource.java
new file mode 100644
index 0000000000..830cdfef5a
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/NonConfigResource.java
@@ -0,0 +1,95 @@
+package org.onap.config;
+
+import java.io.File;
+import java.net.URL;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.Predicate;
+
+/**
+ * The type Non config resource.
+ */
+public class NonConfigResource {
+
+ private static Set<URL> urls = new HashSet<>();
+ private static Set<File> files = new HashSet<>();
+
+ /**
+ * Add.
+ *
+ * @param url the url
+ */
+ public static void add(URL url) {
+ urls.add(url);
+ }
+
+ /**
+ * Add.
+ *
+ * @param file the file
+ */
+ public static void add(File file) {
+ files.add(file);
+ }
+
+ /**
+ * Locate path.
+ *
+ * @param resource the resource
+ * @return the path
+ */
+ public static Path locate(String resource) {
+ try {
+ if (resource != null) {
+ File file = new File(resource);
+ if (file.exists()) {
+ return Paths.get(resource);
+ }
+ for (File availableFile : files) {
+ if (availableFile.getAbsolutePath().endsWith(resource) && availableFile.exists()) {
+ return Paths.get(availableFile.getAbsolutePath());
+ }
+ }
+ if (System.getProperty("node.config.location") != null) {
+ Path path = locate(new File(System.getProperty("node.config.location")), resource);
+ if (path != null) {
+ return path;
+ }
+ }
+ if (System.getProperty("config.location") != null) {
+ Path path = locate(new File(System.getProperty("config.location")), resource);
+ if (path != null) {
+ return path;
+ }
+ }
+ for (URL url : urls) {
+ if (url.getFile().endsWith(resource)) {
+ return Paths.get(url.toURI());
+ }
+ }
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ return null;
+ }
+
+ private static Path locate(File root, String resource) {
+ if (root.exists()) {
+ Collection<File> filesystemResources = ConfigurationUtils.getAllFiles(root, true, false);
+ Predicate<File> f1 = ConfigurationUtils::isConfig;
+ for (File file : filesystemResources) {
+ if (!f1.test(file)) {
+ add(file);
+ if (file.getAbsolutePath().endsWith(resource)) {
+ return Paths.get(file.getAbsolutePath());
+ }
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/AgglomerateConfiguration.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/AgglomerateConfiguration.java
new file mode 100644
index 0000000000..0934608c93
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/AgglomerateConfiguration.java
@@ -0,0 +1,33 @@
+package org.onap.config.impl;
+
+import org.apache.commons.configuration2.DatabaseConfiguration;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * The type Agglomerate configuration.
+ */
+public class AgglomerateConfiguration extends DatabaseConfiguration {
+
+ private final Map<String, Object> store =
+ Collections.synchronizedMap(new WeakHashMap<String, Object>());
+
+ /**
+ * Gets property value.
+ *
+ * @param key the key
+ * @return the property value
+ */
+ public Object getPropertyValue(String key) {
+ Object objToReturn;
+ objToReturn = store.get(key);
+ if (objToReturn == null && !store.containsKey(key)) {
+ objToReturn = super.getProperty(key);
+ store.put(key, objToReturn);
+ }
+ return objToReturn;
+ }
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/AggregateConfiguration.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/AggregateConfiguration.java
new file mode 100644
index 0000000000..c8d76d9bd9
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/AggregateConfiguration.java
@@ -0,0 +1,172 @@
+package org.onap.config.impl;
+
+import org.apache.commons.configuration2.CombinedConfiguration;
+import org.apache.commons.configuration2.Configuration;
+import org.apache.commons.configuration2.tree.MergeCombiner;
+import org.apache.commons.configuration2.tree.OverrideCombiner;
+import org.apache.commons.configuration2.tree.UnionCombiner;
+import static org.onap.config.Constants.LOAD_ORDER_KEY;
+import org.onap.config.ConfigurationUtils;
+import org.onap.config.type.ConfigurationMode;
+
+import java.io.File;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.*;
+
+/**
+ * The type Aggregate configuration.
+ */
+public final class AggregateConfiguration {
+
+ private Map<String, Configuration> rootConfig = new HashMap<>();
+ private Map<String, Configuration> unionConfig = new HashMap<>();
+ private Map<String, Configuration> mergeConfig = new HashMap<>();
+ private Map<String, Configuration> overrideConfig = new LinkedHashMap<>();
+
+ /**
+ * Instantiates a new Aggregate configuration.
+ */
+ public AggregateConfiguration() {
+ try {
+ Class clazz = Class.forName(Thread.currentThread().getStackTrace()[2].getClassName());
+ if (!clazz.getCanonicalName()
+ .equals(ConfigurationImpl.class.getCanonicalName())) {
+ throw new RuntimeException("Illegal access.");
+ }
+ } catch (ClassNotFoundException cfe) {
+ throw new RuntimeException("Class not found while loading change notifier");
+ }
+ }
+
+ private void addConfig(String path, ConfigurationMode configMode, Configuration config) {
+ if (configMode != null) {
+ switch (configMode) {
+ case MERGE:
+ mergeConfig.put(path, config);
+ break;
+ case OVERRIDE:
+ overrideConfig.put(path, config);
+ break;
+ case UNION:
+ unionConfig.put(path, config);
+ break;
+ default:
+ }
+ } else {
+ rootConfig.put(path, config);
+ }
+ }
+
+ /**
+ * Add config.
+ *
+ * @param file the file
+ * @throws Exception the exception
+ */
+ public void addConfig(File file) throws Exception {
+ addConfig(file.getAbsolutePath().toUpperCase(), ConfigurationUtils.getMergeStrategy(file),
+ ConfigurationUtils.getConfigurationBuilder(file, false).getConfiguration());
+ }
+
+ /**
+ * Add config.
+ *
+ * @param url the url
+ * @throws Exception the exception
+ */
+ public void addConfig(URL url) throws Exception {
+ addConfig(url.getFile().toUpperCase(), ConfigurationUtils.getMergeStrategy(url),
+ ConfigurationUtils.getConfigurationBuilder(url).getConfiguration());
+ }
+
+ /**
+ * Remove config.
+ *
+ * @param file the file
+ */
+ public void removeConfig(File file) {
+ String key = file.getAbsolutePath().toUpperCase();
+ if (rootConfig.containsKey(key)) {
+ rootConfig.remove(key);
+ } else if (mergeConfig.containsKey(key)) {
+ mergeConfig.remove(key);
+ } else if (unionConfig.containsKey(key)) {
+ unionConfig.remove(key);
+ } else if (overrideConfig.containsKey(key)) {
+ overrideConfig.remove(key);
+ }
+ }
+
+ /**
+ * Contains config boolean.
+ *
+ * @param file the file
+ * @return the boolean
+ */
+ public boolean containsConfig(File file) {
+ String key = file.getAbsolutePath().toUpperCase();
+ return rootConfig.containsKey(key) || mergeConfig.containsKey(key)
+ || unionConfig.containsKey(key) || overrideConfig.containsKey(key);
+ }
+
+ /**
+ * Gets final configuration.
+ *
+ * @return the final configuration
+ */
+ public Configuration getFinalConfiguration() {
+ CombinedConfiguration ccRoot = new CombinedConfiguration(new MergeCombiner());
+ ArrayList<Configuration> tempList = new ArrayList<>(rootConfig.values());
+ Collections.sort(tempList, this::sortForMerge);
+ for (Configuration conf : tempList) {
+ ccRoot.addConfiguration(conf);
+ }
+ CombinedConfiguration ccMergeRoot = new CombinedConfiguration(new MergeCombiner());
+ ccMergeRoot.addConfiguration(ccRoot);
+ tempList = new ArrayList<>(mergeConfig.values());
+ Collections.sort(tempList, this::sortForMerge);
+ for (Configuration conf : tempList) {
+ ccMergeRoot.addConfiguration(conf);
+ }
+ CombinedConfiguration ccUnionRoot = new CombinedConfiguration(new UnionCombiner());
+ ccUnionRoot.addConfiguration(ccMergeRoot);
+ for (Configuration conf : unionConfig.values()) {
+ ccUnionRoot.addConfiguration(conf);
+ }
+ ArrayList<Configuration> tempOverrideConfigs = new ArrayList<>(overrideConfig.values());
+ Collections.reverse(tempOverrideConfigs);
+ Collections.sort(tempOverrideConfigs, this::sortForOverride);
+ CombinedConfiguration ccOverrideRoot = new CombinedConfiguration(new OverrideCombiner());
+ for (Configuration conf : tempOverrideConfigs) {
+ ccOverrideRoot.addConfiguration(conf);
+ }
+ ccOverrideRoot.addConfiguration(ccUnionRoot);
+ return ccOverrideRoot;
+ }
+
+ private int sortForOverride(Configuration conf1, Configuration conf2){
+ String order1 = conf1.getString(LOAD_ORDER_KEY);
+ String order2 = conf2.getString(LOAD_ORDER_KEY);
+ if (ConfigurationUtils.isBlank(order1) || !order1.trim().matches("\\d+")){
+ order1 = "0";
+ }
+ if (ConfigurationUtils.isBlank(order2) || !order2.trim().matches("\\d+")){
+ order2 = "0";
+ }
+ return Integer.parseInt(order2.trim())-Integer.parseInt(order1.trim());
+ }
+
+ private int sortForMerge(Configuration conf1, Configuration conf2){
+ String order1 = conf1.getString(LOAD_ORDER_KEY);
+ String order2 = conf2.getString(LOAD_ORDER_KEY);
+ if (ConfigurationUtils.isBlank(order1) || !order1.trim().matches("\\d+")){
+ order1 = "0";
+ }
+ if (ConfigurationUtils.isBlank(order2) || !order2.trim().matches("\\d+")){
+ order2 = "0";
+ }
+ return Integer.parseInt(order1.trim())-Integer.parseInt(order2.trim());
+ }
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/CliConfigurationImpl.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/CliConfigurationImpl.java
new file mode 100644
index 0000000000..3bdebffb48
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/CliConfigurationImpl.java
@@ -0,0 +1,354 @@
+package org.onap.config.impl;
+
+import static org.onap.config.Constants.DB_NAMESPACE;
+import static org.onap.config.Constants.DEFAULT_NAMESPACE;
+import static org.onap.config.Constants.DEFAULT_TENANT;
+import static org.onap.config.Constants.KEY_ELEMENTS_DELEMETER;
+import static org.onap.config.Constants.LOAD_ORDER_KEY;
+import static org.onap.config.Constants.MBEAN_NAME;
+import static org.onap.config.Constants.MODE_KEY;
+import static org.onap.config.Constants.NAMESPACE_KEY;
+
+import org.apache.commons.configuration2.CombinedConfiguration;
+import org.apache.commons.configuration2.CompositeConfiguration;
+import org.apache.commons.configuration2.Configuration;
+import org.apache.commons.configuration2.FileBasedConfiguration;
+import org.apache.commons.configuration2.PropertiesConfiguration;
+import org.onap.config.type.ConfigurationQuery;
+import org.onap.config.ConfigurationUtils;
+import org.onap.config.Constants;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.api.Hint;
+import org.onap.config.type.ConfigurationUpdate;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerDelegate;
+import javax.management.MBeanServerNotification;
+import javax.management.Notification;
+import javax.management.ObjectName;
+import javax.management.StandardMBean;
+
+/**
+ * The type Cli configuration.
+ */
+public final class CliConfigurationImpl extends ConfigurationImpl implements ConfigurationManager {
+
+ /**
+ * Instantiates a new Cli configuration.
+ *
+ * @throws Exception the exception
+ */
+ public CliConfigurationImpl() throws Exception {
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ ObjectName name = new ObjectName(MBEAN_NAME);
+ if (mbs.isRegistered(name)) {
+ mbs.unregisterMBean(name);
+ }
+ mbs.registerMBean(new StandardMBean(this, ConfigurationManager.class), name);
+ //mbs.registerMBean(getMBean(), name);
+ mbs.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME, this::handleNotification, null,
+ null);
+ //mbs.addNotificationListener(name, this::handleNotification, null, null);
+ }
+
+
+ /**
+ * Handle notification.
+ *
+ * @param notification the notification
+ * @param handback the handback
+ */
+ public void handleNotification(Notification notification, Object handback) {
+ if (notification instanceof MBeanServerNotification) {
+ MBeanServerNotification mbs = (MBeanServerNotification) notification;
+ if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(mbs.getType())) {
+ try {
+ String mbean =
+ ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DB_NAMESPACE)
+ .getString("shutdown.mbean");
+ if (mbs.getMBeanName()
+ .equals(mbean == null ? new ObjectName(MBEAN_NAME) : new ObjectName(mbean))) {
+ changeNotifier.shutdown();
+ ConfigurationDataSource.lookup().close();
+ }
+ } catch (Exception exception) {
+ //do nothing.
+ }
+ } else if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(mbs.getType())) {
+ mbs.getMBeanName();
+ }
+ }
+ }
+
+ public String getConfigurationValue(Map<String, Object> input) {
+ return getConfigurationValue((ConfigurationQuery) getInput(input));
+ }
+
+ private String getConfigurationValue(ConfigurationQuery queryData) {
+ try {
+ if (queryData.isFallback()) {
+ return ConfigurationUtils.getCommaSeparatedList(
+ get(queryData.getTenant(), queryData.getNamespace(), queryData.getKey(), String[].class,
+ queryData.isLatest() ? Hint.LATEST_LOOKUP : Hint.DEFAULT,
+ queryData.isExternalLookup() ? Hint.EXTERNAL_LOOKUP : Hint.DEFAULT,
+ queryData.isNodeSpecific() ? Hint.NODE_SPECIFIC : Hint.DEFAULT));
+ } else {
+ String[] list =
+ getInternal(queryData.getTenant(), queryData.getNamespace(), queryData.getKey(),
+ String[].class, queryData.isLatest() ? Hint.LATEST_LOOKUP : Hint.DEFAULT,
+ queryData.isExternalLookup() ? Hint.EXTERNAL_LOOKUP : Hint.DEFAULT,
+ queryData.isNodeSpecific() ? Hint.NODE_SPECIFIC : Hint.DEFAULT);
+ return ConfigurationUtils
+ .getCommaSeparatedList(list == null ? Arrays.asList() : Arrays.asList(list));
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ return null;
+ }
+
+ public void updateConfigurationValue(Map<String, Object> input) {
+ updateConfigurationValue((ConfigurationUpdate) getInput(input));
+ }
+
+ private void updateConfigurationValue(ConfigurationUpdate updateData) {
+
+ try {
+ if (!ConfigurationRepository.lookup().isValidTenant(updateData.getTenant())) {
+ throw new RuntimeException("Invalid tenantId.");
+ }
+ if (!ConfigurationRepository.lookup().isValidNamespace(updateData.getNamespace())) {
+ throw new RuntimeException("Invalid Namespace.");
+ }
+ } catch (NullPointerException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
+
+ try {
+ boolean keyPresent =
+ isKeyExists(updateData.getTenant(), updateData.getNamespace(), updateData.getKey());
+ if (keyPresent) {
+ boolean isUpdated = false;
+ Object[] paramArray = new Object[]{
+ updateData.getTenant() + KEY_ELEMENTS_DELEMETER + updateData.getNamespace(),
+ new Long(System.currentTimeMillis()), updateData.getKey(),
+ getConfigurationValue(updateData), updateData.getValue()};
+ Configuration config = ConfigurationRepository.lookup()
+ .getConfigurationFor(updateData.getTenant(), updateData.getNamespace());
+ if (config instanceof AgglomerateConfiguration || config instanceof CombinedConfiguration) {
+ CompositeConfiguration cc = new CompositeConfiguration();
+ cc.addConfiguration(config);
+ config = cc;
+ }
+ CompositeConfiguration configuration = (CompositeConfiguration) config;
+ int overrideIndex = -1;
+ for (int i = 0; i < configuration.getNumberOfConfigurations(); i++) {
+ if (!updateData.isNodeOverride()
+ && (configuration.getConfiguration(i) instanceof AgglomerateConfiguration
+ || configuration.getConfiguration(i) instanceof CombinedConfiguration)) {
+ configuration.getConfiguration(i)
+ .setProperty(updateData.getKey(), updateData.getValue());
+ isUpdated = true;
+ break;
+ } else if (updateData.isNodeOverride()
+ && configuration.getConfiguration(i) instanceof FileBasedConfiguration) {
+ configuration.getConfiguration(i)
+ .setProperty(updateData.getKey(), updateData.getValue());
+ isUpdated = true;
+ overrideIndex = i;
+ break;
+ }
+ }
+ if (!isUpdated) {
+ if (updateData.isNodeOverride()) {
+ PropertiesConfiguration pc = new PropertiesConfiguration();
+ pc.setProperty(NAMESPACE_KEY,
+ updateData.getTenant() + Constants.TENANT_NAMESPACE_SAPERATOR
+ + updateData.getNamespace());
+ pc.setProperty(MODE_KEY, "OVERRIDE");
+ pc.setProperty(updateData.getKey(), updateData.getValue());
+ if (System.getProperty("node.config.location") != null
+ && System.getProperty("node.config.location").trim().length() > 0) {
+ File file = new File(System.getProperty("node.config.location"),
+ updateData.getTenant() + File.separator + updateData.getNamespace()
+ + File.separator + "config.properties");
+ file.getParentFile().mkdirs();
+ PrintWriter out = new PrintWriter(file);
+ pc.write(out);
+ out.close();
+ ConfigurationRepository.lookup().populateOverrideConfigurtaion(
+ updateData.getTenant() + KEY_ELEMENTS_DELEMETER + updateData.getNamespace(),
+ file);
+ }
+ } else {
+ configuration.getConfiguration(0)
+ .setProperty(updateData.getKey(), updateData.getValue());
+ }
+ }
+ if (!updateData.isNodeOverride()) {
+ ConfigurationUtils.executeInsertSql(
+ ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DB_NAMESPACE)
+ .getString("insertconfigurationchangecql"), paramArray);
+ } else {
+ ConfigurationRepository.lookup().refreshOverrideConfigurtaionFor(
+ updateData.getTenant() + KEY_ELEMENTS_DELEMETER + updateData.getNamespace(),
+ overrideIndex);
+ }
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ }
+
+ private boolean isKeyExists(String tenant, String namespace, String key) {
+ boolean keyExist = false;
+ try {
+ keyExist =
+ ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace).containsKey(key);
+ if (!keyExist && !DEFAULT_TENANT.equals(tenant)) {
+ keyExist = ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, namespace)
+ .containsKey(key);
+ }
+ if (!keyExist && !DEFAULT_NAMESPACE.equals(namespace)) {
+ keyExist = ConfigurationRepository.lookup().getConfigurationFor(tenant, DEFAULT_NAMESPACE)
+ .containsKey(key);
+ }
+ if (!keyExist && !DEFAULT_TENANT.equals(tenant) && !DEFAULT_NAMESPACE.equals(namespace)) {
+ keyExist =
+ ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DEFAULT_NAMESPACE)
+ .containsKey(key);
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ return keyExist;
+ }
+
+ public Map<String, String> listConfiguration(Map<String, Object> input) {
+ return listConfiguration((ConfigurationQuery) getInput(input));
+ }
+
+ private Map<String, String> listConfiguration(ConfigurationQuery query) {
+ Map<String, String> map = new HashMap<>();
+ try {
+ Collection<String> keys = getKeys(query.getTenant(), query.getNamespace());
+ for (String key : keys) {
+ map.put(key, getConfigurationValue(query.key(key)));
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ return null;
+ }
+ return map;
+ }
+
+ @Override
+ public boolean updateConfigurationValues(String tenant, String namespace,
+ Map configKeyValueStore) {
+ boolean valueToReturn = true;
+ Iterator<String> keys = configKeyValueStore.keySet().iterator();
+ while (keys.hasNext()) {
+ try {
+ String key = keys.next();
+ ConfigurationUpdate updateData = new ConfigurationUpdate();
+ updateData.tenant(tenant).namespace(namespace).key(key);
+ updateData.value(configKeyValueStore.get(key).toString());
+ updateConfigurationValue(updateData);
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ valueToReturn = false;
+ }
+ }
+ return valueToReturn;
+ }
+
+ private Object getInput(Map<String, Object> input) {
+ Object toReturn = null;
+ try {
+ toReturn = Class.forName(input.get("ImplClass").toString()).newInstance();
+ Method[] methods = toReturn.getClass().getMethods();
+ for (Method method : methods) {
+ if (input.containsKey(method.getName())) {
+ method.invoke(toReturn, input.get(method.getName()));
+ }
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+
+ return toReturn;
+ }
+
+ @Override
+ public Collection<String> getTenants() {
+ return ConfigurationRepository.lookup().getTenants();
+ }
+
+ @Override
+ public Collection<String> getNamespaces() {
+ return ConfigurationRepository.lookup().getNamespaces();
+ }
+
+ private ArrayList<String> getInMemoryKeys(String tenant, String namespace) {
+ ArrayList<String> keys = new ArrayList<>();
+
+ try {
+ Iterator<String> iter =
+ ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace).getKeys();
+ while (iter.hasNext()) {
+ String key = iter.next();
+ if (!(key.equals(NAMESPACE_KEY) || key.equals(MODE_KEY)
+ || key.equals(LOAD_ORDER_KEY))) {
+ keys.add(key);
+ }
+ }
+ } catch (Exception exception) {
+ //do nothing
+ }
+
+ return keys;
+ }
+
+ @Override
+ public Collection<String> getKeys(String tenant, String namespace) {
+ Set<String> keyCollection = new HashSet<>();
+ try {
+ keyCollection.addAll(ConfigurationUtils.executeSelectSql(
+ ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DB_NAMESPACE)
+ .getString("fetchkeysql"),
+ new String[]{tenant + KEY_ELEMENTS_DELEMETER + DEFAULT_NAMESPACE}));
+ keyCollection.addAll(ConfigurationUtils.executeSelectSql(
+ ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DB_NAMESPACE)
+ .getString("fetchkeysql"),
+ new String[]{tenant + KEY_ELEMENTS_DELEMETER + namespace}));
+ keyCollection.addAll(ConfigurationUtils.executeSelectSql(
+ ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DB_NAMESPACE)
+ .getString("fetchkeysql"),
+ new String[]{DEFAULT_TENANT + KEY_ELEMENTS_DELEMETER + namespace}));
+ keyCollection.addAll(ConfigurationUtils.executeSelectSql(
+ ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DB_NAMESPACE)
+ .getString("fetchkeysql"),
+ new String[]{DEFAULT_TENANT + KEY_ELEMENTS_DELEMETER + DEFAULT_NAMESPACE}));
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ keyCollection.addAll(getInMemoryKeys(tenant, DEFAULT_NAMESPACE));
+ keyCollection.addAll(getInMemoryKeys(tenant, namespace));
+ keyCollection.addAll(getInMemoryKeys(DEFAULT_TENANT, namespace));
+ keyCollection.addAll(getInMemoryKeys(DEFAULT_TENANT, DEFAULT_NAMESPACE));
+ }
+ return keyCollection;
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationChangeNotifier.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationChangeNotifier.java
new file mode 100644
index 0000000000..a7c10caae9
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationChangeNotifier.java
@@ -0,0 +1,474 @@
+package org.onap.config.impl;
+
+import org.onap.config.ConfigurationUtils;
+import org.onap.config.Constants;
+import org.onap.config.api.ConfigurationChangeListener;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.api.Hint;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Method;
+import java.nio.file.ClosedWatchServiceException;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.StandardWatchEventKinds;
+import java.nio.file.WatchEvent;
+import java.nio.file.WatchKey;
+import java.nio.file.WatchService;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.Vector;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import javax.management.JMX;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+
+/**
+ * The type Configuration change notifier.
+ */
+public final class ConfigurationChangeNotifier {
+
+ private final HashMap<String, List<NotificationData>> store = new HashMap<>();
+ private final ScheduledExecutorService executor =
+ Executors.newScheduledThreadPool(5, ConfigurationUtils.getThreadFactory());
+ private final ExecutorService notificationExecutor =
+ Executors.newCachedThreadPool(ConfigurationUtils.getThreadFactory());
+ private final Map<String, WatchService> watchServiceCollection =
+ Collections.synchronizedMap(new HashMap<>());
+
+ static {
+ if (!Thread.currentThread().getStackTrace()[2].getClassName()
+ .equals(ConfigurationImpl.class.getName())) {
+ throw new RuntimeException("Illegal access.");
+ }
+ }
+
+ /**
+ * Instantiates a new Configuration change notifier.
+ *
+ * @param inMemoryConfig the in memory config
+ */
+ public ConfigurationChangeNotifier(Map<String, AggregateConfiguration> inMemoryConfig) {
+ executor.scheduleWithFixedDelay(() -> this
+ .pollFilesystemAndUpdateConfigurationIfRequired(inMemoryConfig,
+ System.getProperty("config.location"), false), 1, 1, TimeUnit.MILLISECONDS);
+ executor.scheduleWithFixedDelay(() -> this
+ .pollFilesystemAndUpdateConfigurationIfRequired(inMemoryConfig,
+ System.getProperty("tenant.config.location"), true), 1, 1, TimeUnit.MILLISECONDS);
+ executor.scheduleWithFixedDelay(() -> this
+ .pollFilesystemAndUpdateNodeSpecificConfigurationIfRequired(
+ System.getProperty("node.config.location")), 1, 1, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Shutdown.
+ */
+ public void shutdown() {
+ for (WatchService watch : watchServiceCollection.values()) {
+ try {
+ watch.close();
+ } catch (IOException exception) {
+ //do nothing
+ }
+ }
+ executor.shutdownNow();
+ }
+
+ /**
+ * Poll filesystem and update configuration if required.
+ *
+ * @param inMemoryConfig the in memory config
+ * @param location the location
+ * @param isTenantLocation the is tenant location
+ */
+ public void pollFilesystemAndUpdateConfigurationIfRequired(
+ Map<String, AggregateConfiguration> inMemoryConfig, String location,
+ boolean isTenantLocation) {
+ try {
+ Set<Path> paths = watchForChange(location);
+ if (paths != null) {
+ for (Path path : paths) {
+ File file = path.toAbsolutePath().toFile();
+ String repositoryKey = null;
+ if (ConfigurationUtils.isConfig(file) && file.isFile()) {
+ if (isTenantLocation) {
+ Collection<File> tenantsRoot =
+ ConfigurationUtils.getAllFiles(new File(location), false, true);
+ for (File tenantRoot : tenantsRoot) {
+ if (file.getAbsolutePath().startsWith(tenantRoot.getAbsolutePath())) {
+ repositoryKey = ConfigurationUtils.getConfigurationRepositoryKey(
+ (tenantRoot.getName() + Constants.TENANT_NAMESPACE_SAPERATOR
+ + ConfigurationUtils.getNamespace(file))
+ .split(Constants.TENANT_NAMESPACE_SAPERATOR));
+ }
+ }
+ } else {
+ repositoryKey = ConfigurationUtils.getConfigurationRepositoryKey(file);
+ }
+ AggregateConfiguration config = inMemoryConfig.get(repositoryKey);
+ if (config != null) {
+ LinkedHashMap origConfig = ConfigurationUtils.toMap(config.getFinalConfiguration());
+ config.addConfig(file);
+ LinkedHashMap latestConfig = ConfigurationUtils.toMap(config.getFinalConfiguration());
+ Map map = ConfigurationUtils.diff(origConfig, latestConfig);
+ String[] tenantNamespaceArray =
+ repositoryKey.split(Constants.KEY_ELEMENTS_DELEMETER);
+ updateConfigurationValues(tenantNamespaceArray[0], tenantNamespaceArray[1], map);
+ }
+ } else {
+ for (String configKey : inMemoryConfig.keySet()) {
+ repositoryKey = configKey;
+ AggregateConfiguration config = inMemoryConfig.get(repositoryKey);
+ if (config.containsConfig(file)) {
+ LinkedHashMap origConfig = ConfigurationUtils.toMap(config.getFinalConfiguration());
+ config.removeConfig(file);
+ LinkedHashMap latestConfig =
+ ConfigurationUtils.toMap(config.getFinalConfiguration());
+ Map map = ConfigurationUtils.diff(origConfig, latestConfig);
+ String[] tenantNamespaceArray =
+ repositoryKey.split(Constants.KEY_ELEMENTS_DELEMETER);
+ updateConfigurationValues(tenantNamespaceArray[0], tenantNamespaceArray[1],
+ map);
+ }
+ }
+ }
+ }
+ }
+ } catch (ClosedWatchServiceException exception) {
+ // do nothing.
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ }
+
+ private void updateConfigurationValues(String tenant, String namespace, Map map)
+ throws Exception {
+ MBeanServerConnection mbsc = ManagementFactory.getPlatformMBeanServer();
+ ObjectName mbeanName = new ObjectName(Constants.MBEAN_NAME);
+ ConfigurationManager conf =
+ JMX.newMBeanProxy(mbsc, mbeanName, ConfigurationManager.class,
+ true);
+ conf.updateConfigurationValues(tenant, namespace, map);
+ }
+
+ /**
+ * Poll filesystem and update node specific configuration if required.
+ *
+ * @param location the location
+ */
+ public void pollFilesystemAndUpdateNodeSpecificConfigurationIfRequired(String location) {
+ try {
+ Set<Path> paths = watchForChange(location);
+ if (paths != null) {
+ for (Path path : paths) {
+ File file = path.toAbsolutePath().toFile();
+
+ if (ConfigurationUtils.isConfig(file)) {
+ String repositoryKey = ConfigurationUtils.getConfigurationRepositoryKey(file);
+ ConfigurationRepository.lookup().populateOverrideConfigurtaion(repositoryKey, file);
+ } else {
+ ConfigurationRepository.lookup().removeOverrideConfigurtaion(file);
+ }
+ }
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ }
+
+ /**
+ * Notify changes towards.
+ *
+ * @param tenant the tenant
+ * @param component the component
+ * @param key the key
+ * @param myself the myself
+ * @throws Exception the exception
+ */
+ public void notifyChangesTowards(String tenant, String component, String key,
+ ConfigurationChangeListener myself) throws Exception {
+ List<NotificationData> notificationList =
+ store.get(tenant + Constants.KEY_ELEMENTS_DELEMETER + component);
+ if (notificationList == null) {
+ notificationList = Collections.synchronizedList(new ArrayList<NotificationData>());
+ store.put(tenant + Constants.KEY_ELEMENTS_DELEMETER + component, notificationList);
+ executor.scheduleWithFixedDelay(
+ () -> triggerScanning(tenant + Constants.KEY_ELEMENTS_DELEMETER + component), 1, 30000,
+ TimeUnit.MILLISECONDS);
+ }
+ notificationList.add(new NotificationData(tenant, component, key, myself));
+ }
+
+ /**
+ * Stop notification towards.
+ *
+ * @param tenant the tenant
+ * @param component the component
+ * @param key the key
+ * @param myself the myself
+ * @throws Exception the exception
+ */
+ public void stopNotificationTowards(String tenant, String component, String key,
+ ConfigurationChangeListener myself) throws Exception {
+ List<NotificationData> notificationList =
+ store.get(tenant + Constants.KEY_ELEMENTS_DELEMETER + component);
+ if (notificationList != null) {
+ boolean removed =
+ notificationList.remove(new NotificationData(tenant, component, key, myself));
+ if (removed && notificationList.isEmpty()) {
+ store.remove(tenant + Constants.KEY_ELEMENTS_DELEMETER + component);
+ }
+ }
+
+ }
+
+ private void triggerScanning(String key) {
+ if (store.get(key) != null) {
+ notificationExecutor.submit(() -> scanForChanges(key));
+ } else {
+ throw new IllegalArgumentException("Notification service for " + key + " is suspended.");
+ }
+ }
+
+ private void scanForChanges(String key) {
+ List<NotificationData> list = store.get(key);
+ if (list != null) {
+ list.stream()
+ .filter(NotificationData::isChanged)
+ .forEach(notificationData -> notificationExecutor.submit(() -> sendNotification(notificationData)));
+ }
+ }
+
+ private void sendNotification(NotificationData notificationData) {
+ try {
+ notificationData.dispatchNotification();
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ }
+
+ private Set<Path> watchForChange(String location) throws Exception {
+ if (location == null || location.trim().length() == 0) {
+ return null;
+ }
+ File file = new File(location);
+ if (!file.exists()) {
+ return null;
+ }
+ Path path = file.toPath();
+ Set<Path> toReturn = new HashSet<>();
+ try (final WatchService watchService = FileSystems.getDefault().newWatchService()) {
+ watchServiceCollection.put(location, watchService);
+ path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY,
+ StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE);
+ for (File dir : ConfigurationUtils.getAllFiles(file, true, true)) {
+ dir.toPath().register(watchService, StandardWatchEventKinds.ENTRY_MODIFY,
+ StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE);
+ }
+ while (true) {
+ final WatchKey wk = watchService.take();
+ Thread.sleep(ConfigurationRepository.lookup()
+ .getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
+ .getLong("event.fetch.delay"));
+ for (WatchEvent<?> event : wk.pollEvents()) {
+ Object context = event.context();
+ if (context instanceof Path) {
+ File newFile = new File(((Path) wk.watchable()).toFile(), context.toString());
+ if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
+ if (newFile.isDirectory()) {
+ newFile.toPath().register(watchService, StandardWatchEventKinds.ENTRY_MODIFY,
+ StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE);
+ continue;
+ }
+ } else if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) {
+ if (newFile.isDirectory()) {
+ continue;
+ }
+ }
+ toReturn.add(newFile.toPath());
+ }
+ }
+ if (toReturn.isEmpty()) {
+ continue;
+ }
+ break;
+ }
+ }
+ return toReturn;
+ }
+
+ /**
+ * The type Notification data.
+ */
+ static class NotificationData {
+
+ /**
+ * The Tenant.
+ */
+ final String tenant;
+ /**
+ * The Namespace.
+ */
+ final String namespace;
+ /**
+ * The Key.
+ */
+ final String key;
+ /**
+ * The Myself.
+ */
+ final ConfigurationChangeListener myself;
+ /**
+ * The Current value.
+ */
+ Object currentValue;
+ /**
+ * The Is array.
+ */
+ boolean isArray;
+
+ /**
+ * Instantiates a new Notification data.
+ *
+ * @param tenant the tenant
+ * @param component the component
+ * @param key the key
+ * @param myself the myself
+ * @throws Exception the exception
+ */
+ public NotificationData(String tenant, String component, String key,
+ ConfigurationChangeListener myself) throws Exception {
+ this.tenant = tenant;
+ this.namespace = component;
+ this.key = key;
+ this.myself = myself;
+ if (!ConfigurationRepository.lookup().getConfigurationFor(tenant, component)
+ .containsKey(key)) {
+ throw new RuntimeException("Key[" + key + "] not found.");
+ }
+ isArray = ConfigurationUtils.isArray(tenant, component, key, Hint.DEFAULT.value());
+ if (isArray) {
+ currentValue = ConfigurationManager.lookup().getAsStringValues(tenant, component, key);
+ } else {
+ currentValue = ConfigurationManager.lookup().getAsString(tenant, component, key);
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof NotificationData)) {
+ return false;
+ }
+ NotificationData nd = (NotificationData) obj;
+ return Objects.equals(tenant, nd.tenant)
+ && Objects.equals(namespace, nd.namespace)
+ && Objects.equals(key, nd.key)
+ && Objects.equals(myself, nd.myself)
+ && Objects.equals(currentValue, nd.currentValue) // it's either String or List<String>
+ && isArray == nd.isArray;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(tenant, namespace, key, myself, currentValue, isArray);
+ }
+
+ /**
+ * Is changed boolean.
+ *
+ * @return the boolean
+ */
+ public boolean isChanged() {
+ Object latestValue;
+ try {
+ if (isArray) {
+ latestValue = ConfigurationManager.lookup().getAsStringValues(tenant, namespace, key);
+ } else {
+ latestValue = ConfigurationManager.lookup().getAsString(tenant, namespace, key);
+ }
+ if (!isArray) {
+ return !currentValue.equals(latestValue);
+ } else {
+ Collection<String> oldCollection = (Collection<String>) currentValue;
+ Collection<String> newCollection = (Collection<String>) latestValue;
+ for (String val : oldCollection) {
+ if (!newCollection.remove(val)) {
+ return true;
+ }
+ }
+ return !newCollection.isEmpty();
+ }
+ } catch (Exception exception) {
+ return false;
+ }
+ }
+
+ /**
+ * Dispatch notification.
+ *
+ * @throws Exception the exception
+ */
+ public void dispatchNotification() throws Exception {
+ Method method = null;
+ Vector<Object> parameters = null;
+ try {
+ Object latestValue;
+ if (isArray) {
+ latestValue = ConfigurationManager.lookup().getAsStringValues(tenant, namespace, key);
+ } else {
+ latestValue = ConfigurationManager.lookup().getAsString(tenant, namespace, key);
+ }
+ Method[] methods = myself.getClass().getDeclaredMethods();
+ if (methods != null && methods.length > 0) {
+ method = methods[0];
+ int paramCount = method.getParameterCount();
+ parameters = new Vector<>();
+ if (paramCount > 4) {
+ if (tenant.equals(Constants.DEFAULT_TENANT)) {
+ parameters.add(null);
+ } else {
+ parameters.add(tenant);
+ }
+ }
+ if (paramCount > 3) {
+ if (namespace.equals(Constants.DEFAULT_NAMESPACE)) {
+ parameters.add(null);
+ } else {
+ parameters.add(namespace);
+ }
+ }
+ parameters.add(key);
+ parameters.add(currentValue);
+ parameters.add(latestValue);
+ method.setAccessible(true);
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ } finally {
+ isArray = ConfigurationUtils.isArray(tenant, namespace, key, Hint.DEFAULT.value());
+ if (isArray) {
+ currentValue = ConfigurationManager.lookup().getAsStringValues(tenant, namespace, key);
+ } else {
+ currentValue = ConfigurationManager.lookup().getAsString(tenant, namespace, key);
+ }
+ if (method != null && parameters != null) {
+ method.invoke(myself, parameters.toArray());
+ }
+ }
+ }
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationDataSource.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationDataSource.java
new file mode 100644
index 0000000000..ea9c61f635
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationDataSource.java
@@ -0,0 +1,105 @@
+package org.onap.config.impl;
+
+import org.apache.commons.configuration2.ImmutableConfiguration;
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.config.ConfigurationUtils;
+import org.onap.config.Constants;
+
+import java.sql.Driver;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.ServiceLoader;
+import java.util.Set;
+
+/**
+ * The type Configuration data source.
+ */
+public final class ConfigurationDataSource {
+
+ private static BasicDataSource configDBDatasource = null;
+ private static Set<String> validCallers = Collections.unmodifiableSet(new HashSet<>(
+ Arrays.asList(ConfigurationUtils.class.getName(), CliConfigurationImpl.class.getName())));
+
+ private ConfigurationDataSource() {
+ //Hide constructor to prevent instantiation using the default implicit constructor
+ }
+
+ static {
+ try {
+ configDBDatasource = initDataSource();
+ } catch (Exception exception) {
+ System.err.println("Datasource initialization error. Configuration management will be using"
+ + "in-memory persistence.");
+ }
+ }
+
+ /**
+ * Lookup basic data source.
+ *
+ * @return the basic data source
+ * @throws Exception the exception
+ */
+ public static BasicDataSource lookup() throws Exception {
+ if (validCallers.contains(Thread.currentThread().getStackTrace()[2].getClassName())) {
+ return configDBDatasource;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Init data source basic data source.
+ *
+ * @return the basic data source
+ * @throws Exception the exception
+ */
+ public static BasicDataSource initDataSource() throws Exception {
+ ImmutableConfiguration dbConfig = ConfigurationRepository.lookup()
+ .getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE);
+ if (StringUtils.isEmpty(dbConfig.getString("dbhost"))) {
+ return null;
+ }
+ BasicDataSource datasource = new BasicDataSource();
+ String driverClassName = dbConfig.getString("driverClassName");
+ String jdbcUrl = dbConfig.getString("jdbcURL");
+ if (!isDriverSuitable(driverClassName, jdbcUrl)) {
+ driverClassName = getDriverFor(jdbcUrl);
+ }
+ datasource.setDriverClassName(driverClassName);
+ datasource.setUrl(jdbcUrl);
+ String dbuser = dbConfig.getString("dbuser");
+ String dbpassword = dbConfig.getString("dbpassword");
+ if (dbuser != null && dbuser.trim().length() > 0) {
+ datasource.setUsername(dbuser);
+ }
+ if (dbpassword != null && dbpassword.trim().length() > 0) {
+ datasource.setPassword(dbpassword);
+ }
+ return datasource;
+ }
+
+ private static boolean isDriverSuitable(String driverClassName, String url) {
+ if (driverClassName == null || driverClassName.trim().length() == 0) {
+ return false;
+ }
+ try {
+ Driver driver = Driver.class.cast(Class.forName(driverClassName).newInstance());
+ return driver.acceptsURL(url);
+ } catch (Exception exception) {
+ return false;
+ }
+ }
+
+ private static String getDriverFor(String url) throws Exception {
+ ServiceLoader<Driver> loader = ServiceLoader.load(Driver.class);
+ for (Driver driver : loader) {
+ if (driver.acceptsURL(url)) {
+ return driver.getClass().getName();
+ }
+ }
+ throw new RuntimeException("No Suitable driver found for " + url);
+ }
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationFilter.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationFilter.java
new file mode 100644
index 0000000000..9df69ed1d7
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationFilter.java
@@ -0,0 +1,39 @@
+package org.onap.config.impl;
+
+import org.onap.config.Constants;
+import org.onap.config.api.Configuration;
+
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.annotation.WebFilter;
+
+@WebFilter("/")
+public class ConfigurationFilter implements Filter {
+
+ @Override
+ public void init(FilterConfig paramFilterConfig) throws ServletException {
+ //Use the default behavior
+ }
+
+ @Override
+ public void doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse,
+ FilterChain paramFilterChain) throws IOException, ServletException {
+ Configuration.tenant.set(Constants.DEFAULT_TENANT);
+ try {
+ paramFilterChain.doFilter(paramServletRequest, paramServletResponse);
+ } finally {
+ Configuration.tenant.remove();
+ }
+ }
+
+ @Override
+ public void destroy() {
+ //Use the default behavior
+ }
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationImpl.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationImpl.java
new file mode 100644
index 0000000000..43b1b96fc5
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationImpl.java
@@ -0,0 +1,679 @@
+package org.onap.config.impl;
+
+import static org.onap.config.ConfigurationUtils.getConfigurationRepositoryKey;
+
+import org.apache.commons.configuration2.Configuration;
+import org.apache.commons.configuration2.DatabaseConfiguration;
+import org.onap.config.ConfigurationUtils;
+import org.onap.config.Constants;
+import org.onap.config.NonConfigResource;
+import org.onap.config.api.Config;
+import org.onap.config.api.ConfigurationChangeListener;
+import org.onap.config.api.Hint;
+
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Predicate;
+
+/**
+ * The type Configuration.
+ */
+public class ConfigurationImpl implements org.onap.config.api.Configuration {
+
+ private static ThreadLocal<String> tenant = new ThreadLocal<String>() {
+ protected String initialValue() {
+ return Constants.DEFAULT_TENANT;
+ }
+
+ ;
+ };
+ private static boolean instantiated = false;
+ /**
+ * The Change notifier.
+ */
+ ConfigurationChangeNotifier changeNotifier;
+
+ /**
+ * Instantiates a new Configuration.
+ *
+ * @throws Exception the exception
+ */
+ public ConfigurationImpl() throws Exception {
+ if (instantiated || !CliConfigurationImpl.class.isAssignableFrom(this.getClass())) {
+ throw new RuntimeException("Illegal access to configuration.");
+ }
+ Map<String, AggregateConfiguration> moduleConfigStore = new HashMap<>();
+ List<URL> classpathResources = ConfigurationUtils.getAllClassPathResources();
+ Predicate<URL> predicate = ConfigurationUtils::isConfig;
+ for (URL url : classpathResources) {
+ if (predicate.test(url)) {
+ String moduleName = ConfigurationUtils.getConfigurationRepositoryKey(url);
+ AggregateConfiguration moduleConfig = moduleConfigStore.get(moduleName);
+ if (moduleConfig == null) {
+ moduleConfig = new AggregateConfiguration();
+ moduleConfigStore.put(moduleName, moduleConfig);
+ }
+ moduleConfig.addConfig(url);
+ } else {
+ NonConfigResource.add(url);
+ }
+ }
+ String configLocation = System.getProperty("config.location");
+ if (configLocation != null && configLocation.trim().length() > 0) {
+ File root = new File(configLocation);
+ Collection<File> filesystemResources = ConfigurationUtils.getAllFiles(root, true, false);
+ Predicate<File> filePredicate = ConfigurationUtils::isConfig;
+ for (File file : filesystemResources) {
+ if (filePredicate.test(file)) {
+ String moduleName = ConfigurationUtils.getConfigurationRepositoryKey(file);
+ AggregateConfiguration moduleConfig = moduleConfigStore.get(moduleName);
+ if (moduleConfig == null) {
+ moduleConfig = new AggregateConfiguration();
+ moduleConfigStore.put(moduleName, moduleConfig);
+ }
+ moduleConfig.addConfig(file);
+ } else {
+ NonConfigResource.add(file);
+ }
+ }
+ }
+ String tenantConfigLocation = System.getProperty("tenant.config.location");
+ if (tenantConfigLocation != null && tenantConfigLocation.trim().length() > 0) {
+ File root = new File(tenantConfigLocation);
+ Collection<File> tenantsRoot = ConfigurationUtils.getAllFiles(root, false, true);
+ Collection<File> filesystemResources = ConfigurationUtils.getAllFiles(root, true, false);
+ Predicate<File> filePredicate = ConfigurationUtils::isConfig;
+ for (File file : filesystemResources) {
+ if (filePredicate.test(file)) {
+ String moduleName = ConfigurationUtils.getNamespace(file);
+ for (File tenanatFileRoot : tenantsRoot) {
+ if (file.getAbsolutePath().startsWith(tenanatFileRoot.getAbsolutePath())) {
+ moduleName = ConfigurationUtils.getConfigurationRepositoryKey(
+ (tenanatFileRoot.getName().toUpperCase() + Constants.TENANT_NAMESPACE_SAPERATOR
+ + moduleName).split(Constants.TENANT_NAMESPACE_SAPERATOR));
+ }
+ }
+ AggregateConfiguration moduleConfig = moduleConfigStore.get(moduleName);
+ if (moduleConfig == null) {
+ moduleConfig = new AggregateConfiguration();
+ moduleConfigStore.put(moduleName, moduleConfig);
+ }
+ moduleConfig.addConfig(file);
+ }
+ }
+ }
+ populateFinalConfigurationIncrementally(moduleConfigStore);
+ ConfigurationRepository.lookup().initTenantsAndNamespaces();
+ String nodeConfigLocation = System.getProperty("node.config.location");
+ if (nodeConfigLocation != null && nodeConfigLocation.trim().length() > 0) {
+ File root = new File(nodeConfigLocation);
+ Collection<File> filesystemResources = ConfigurationUtils.getAllFiles(root, true, false);
+ Predicate<File> filePredicate = ConfigurationUtils::isConfig;
+ for (File file : filesystemResources) {
+ if (filePredicate.test(file)) {
+ ConfigurationRepository.lookup().populateOverrideConfigurtaion(
+ ConfigurationUtils.getConfigurationRepositoryKey(ConfigurationUtils.getNamespace(file)
+ .split(Constants.TENANT_NAMESPACE_SAPERATOR)), file);
+ }
+ }
+ }
+ instantiated = true;
+ changeNotifier = new ConfigurationChangeNotifier(moduleConfigStore);
+ }
+
+ @Override
+ public void addConfigurationChangeListener(String tenant, String namespace, String key,
+ ConfigurationChangeListener myself) {
+ tenant = ConfigurationRepository.lookup().isValidTenant(tenant) ? tenant.toUpperCase()
+ : Constants.DEFAULT_TENANT;
+ namespace =
+ ConfigurationRepository.lookup().isValidNamespace(namespace) ? namespace.toUpperCase()
+ : Constants.DEFAULT_NAMESPACE;
+ if (key == null || key.trim().length() == 0) {
+ throw new IllegalArgumentException("Key can't be null.");
+ }
+ if (myself == null) {
+ throw new IllegalArgumentException("ConfigurationChangeListener instance is null.");
+ }
+ try {
+ changeNotifier.notifyChangesTowards(tenant, namespace, key, myself);
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ }
+
+ private void populateFinalConfigurationIncrementally(Map<String, AggregateConfiguration> configs)
+ throws Exception {
+ boolean isDbAccessible = false;
+ if (configs.get(
+ Constants.DEFAULT_TENANT + Constants.KEY_ELEMENTS_DELEMETER + Constants.DB_NAMESPACE)
+ != null) {
+ ConfigurationRepository.lookup().populateConfigurtaion(
+ Constants.DEFAULT_TENANT + Constants.KEY_ELEMENTS_DELEMETER + Constants.DB_NAMESPACE,
+ configs.remove(
+ Constants.DEFAULT_TENANT + Constants.KEY_ELEMENTS_DELEMETER + Constants.DB_NAMESPACE)
+ .getFinalConfiguration());
+ isDbAccessible = ConfigurationUtils.executeDdlSql(ConfigurationRepository.lookup()
+ .getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
+ .getString("createtablecql"));
+ if (isDbAccessible) {
+ ConfigurationUtils.executeDdlSql(ConfigurationRepository.lookup()
+ .getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
+ .getString("createmonitoringtablecql"));
+ }
+ }
+
+ Set<String> modules = configs.keySet();
+ for (String module : modules) {
+ if (isDbAccessible) {
+ DatabaseConfiguration config =
+ ConfigurationUtils.getDbConfigurationBuilder(module).getConfiguration();
+ Configuration currentConfig = configs.get(module).getFinalConfiguration();
+ Iterator<String> keys = currentConfig.getKeys();
+ while (keys.hasNext()) {
+ String currentKey = keys.next();
+ if (!(Constants.MODE_KEY.equals(currentKey)
+ || Constants.NAMESPACE_KEY.equals(currentKey)
+ || Constants.LOAD_ORDER_KEY.equals(currentKey))) {
+ if (!config.containsKey(currentKey)) {
+ Object propValue = currentConfig.getProperty(currentKey);
+ if (propValue instanceof Collection) {
+ config.addProperty(currentKey, propValue.toString());
+ } else {
+ config.addProperty(currentKey, propValue);
+ }
+ }
+ }
+ }
+ } else {
+ ConfigurationRepository.lookup()
+ .populateConfigurtaion(module, configs.get(module).getFinalConfiguration());
+ }
+ }
+ }
+
+ @Override
+ public <T> T get(String tenant, String namespace, String key, Class<T> clazz, Hint... hints) {
+
+ String[] tenantNamespaceArrayy = null;
+ if (tenant == null && namespace != null
+ && (tenantNamespaceArrayy = namespace.split(Constants.TENANT_NAMESPACE_SAPERATOR)).length
+ > 1) {
+ tenant = tenantNamespaceArrayy[0];
+ namespace = tenantNamespaceArrayy[1];
+ }
+
+ tenant = ConfigurationRepository.lookup().isValidTenant(tenant) ? tenant.toUpperCase()
+ : Constants.DEFAULT_TENANT;
+ namespace =
+ ConfigurationRepository.lookup().isValidNamespace(namespace) ? namespace.toUpperCase()
+ : Constants.DEFAULT_NAMESPACE;
+ T returnValue = null;
+ returnValue = (T) getInternal(tenant, namespace, key,
+ clazz.isPrimitive() ? getWrapperClass(clazz) : clazz,
+ hints == null || hints.length == 0 ? new Hint[]{Hint.EXTERNAL_LOOKUP, Hint.NODE_SPECIFIC}
+ : hints);
+ if ((returnValue == null || ConfigurationUtils.isZeroLengthArray(clazz, returnValue))
+ && !Constants.DEFAULT_TENANT.equals(tenant)) {
+ returnValue = (T) getInternal(Constants.DEFAULT_TENANT, namespace, key,
+ clazz.isPrimitive() ? getWrapperClass(clazz) : clazz,
+ hints == null || hints.length == 0 ? new Hint[]{Hint.EXTERNAL_LOOKUP, Hint.NODE_SPECIFIC}
+ : hints);
+ }
+ if ((returnValue == null || ConfigurationUtils.isZeroLengthArray(clazz, returnValue))
+ && !Constants.DEFAULT_NAMESPACE.equals(namespace)) {
+ returnValue = (T) getInternal(tenant, Constants.DEFAULT_NAMESPACE, key,
+ clazz.isPrimitive() ? getWrapperClass(clazz) : clazz,
+ hints == null || hints.length == 0 ? new Hint[]{Hint.EXTERNAL_LOOKUP, Hint.NODE_SPECIFIC}
+ : hints);
+ }
+ if ((returnValue == null || ConfigurationUtils.isZeroLengthArray(clazz, returnValue))
+ && !Constants.DEFAULT_NAMESPACE.equals(namespace)
+ && !Constants.DEFAULT_TENANT.equals(tenant)) {
+ returnValue = (T) getInternal(Constants.DEFAULT_TENANT, Constants.DEFAULT_NAMESPACE, key,
+ clazz.isPrimitive() ? getWrapperClass(clazz) : clazz,
+ hints == null || hints.length == 0 ? new Hint[]{Hint.EXTERNAL_LOOKUP, Hint.NODE_SPECIFIC}
+ : hints);
+ }
+ if (returnValue == null && clazz.isPrimitive()) {
+ return (T) ConfigurationUtils.getDefaultFor(clazz);
+ } else {
+ return returnValue;
+ }
+ }
+
+
+ /**
+ * Gets internal.
+ *
+ * @param <T> the type parameter
+ * @param tenant the tenant
+ * @param namespace the namespace
+ * @param key the key
+ * @param clazz the clazz
+ * @param hints the hints
+ * @return the internal
+ */
+ protected <T> T getInternal(String tenant, String namespace, String key, Class<T> clazz,
+ Hint... hints) {
+ int processingHints = Hint.DEFAULT.value();
+ if (hints != null) {
+ for (Hint hint : hints) {
+ processingHints = processingHints | hint.value();
+ }
+ }
+
+ if (tenant == null || tenant.trim().length() == 0) {
+ tenant = this.tenant.get();
+ } else {
+ tenant = tenant.toUpperCase();
+ }
+ if (namespace == null || namespace.trim().length() == 0) {
+ namespace = Constants.DEFAULT_NAMESPACE;
+ } else {
+ namespace = namespace.toUpperCase();
+ }
+ if (key == null || key.trim().length() == 0) {
+ if (!clazz.isAnnotationPresent(Config.class)) {
+ throw new IllegalArgumentException("Key can't be null.");
+ }
+ }
+ if (clazz == null) {
+ throw new IllegalArgumentException("clazz is null.");
+ }
+ if (clazz.isPrimitive()) {
+ clazz = getWrapperClass(clazz);
+ }
+ try {
+ if (ConfigurationUtils.isWrapperClass(clazz) || clazz.isPrimitive()) {
+ Object obj =
+ ConfigurationUtils
+ .getProperty(ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace),
+ key, processingHints);
+ if (obj != null) {
+ if (ConfigurationUtils.isCollection(obj.toString())) {
+ obj = ConfigurationUtils.getCollectionString(obj.toString());
+ }
+ String value = obj.toString().split(",")[0];
+ value = ConfigurationUtils.processVariablesIfPresent(tenant, namespace, value);
+ return (T) getValue(value, clazz.isPrimitive() ? getWrapperClass(clazz) : clazz,
+ processingHints);
+ } else {
+ return null;
+ }
+ } else if (clazz.isArray()
+ && (clazz.getComponentType().isPrimitive() || ConfigurationUtils.isWrapperClass(clazz.getComponentType()))) {
+ Object obj =
+ ConfigurationUtils
+ .getProperty(ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace),
+ key, processingHints);
+ if (obj != null) {
+ Class componentClass = clazz.getComponentType();
+ if (clazz.getComponentType().isPrimitive()) {
+ componentClass = getWrapperClass(clazz.getComponentType());
+ }
+ String collString = ConfigurationUtils.getCollectionString(obj.toString());
+ ArrayList<String> tempCollection = new ArrayList<>();
+ for (String itemValue : collString.split(",")) {
+ tempCollection
+ .add(ConfigurationUtils.processVariablesIfPresent(tenant, namespace, itemValue));
+ }
+ Collection<T> collection = convert(
+ ConfigurationUtils.getCollectionString(Arrays.toString(tempCollection.toArray())),
+ componentClass, processingHints);
+ if (clazz.getComponentType().isPrimitive()) {
+ return (T) ConfigurationUtils.getPrimitiveArray(collection, clazz.getComponentType());
+ } else {
+ return (T) collection
+ .toArray(getZeroLengthArrayFor(getWrapperClass(clazz.getComponentType())));
+ }
+ } else {
+ return null;
+ }
+ } else if (clazz.isAnnotationPresent(Config.class)) {
+ return read(tenant, namespace, clazz,
+ (key == null || key.trim().length() == 0) ? "" : (key + "."), hints);
+ } else {
+ throw new IllegalArgumentException(
+ "Only pimitive classes, wrapper classes, corresponding array classes and any "
+ + "class decorated with @org.openecomp.config.api.Config are allowed as argument.");
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ return null;
+ }
+
+
+ private <T> T read(String tenant, String namespace, Class<T> clazz, String keyPrefix,
+ Hint... hints) throws Exception {
+ Config confAnnot =
+ clazz.getAnnotation(Config.class);
+ if (confAnnot != null && confAnnot.key().length()>0 && !keyPrefix.endsWith(".")) {
+ keyPrefix += (confAnnot.key() + ".");
+ }
+ Constructor<T> constructor = clazz.getDeclaredConstructor();
+ constructor.setAccessible(true);
+ T objToReturn = constructor.newInstance();
+ for (Field field : clazz.getDeclaredFields()) {
+ field.setAccessible(true);
+ Config fieldConfAnnot =
+ field.getAnnotation(Config.class);
+ if (fieldConfAnnot != null) {
+ if (field.getType().isPrimitive() || ConfigurationUtils.isWrapperClass(field.getType())
+ || (field.getType().isArray() && (field.getType().getComponentType().isPrimitive()
+ || ConfigurationUtils.isWrapperClass(field.getType().getComponentType())))
+ || field.getType().getAnnotation(Config.class) != null) {
+ field.set(objToReturn,
+ get(tenant, namespace, keyPrefix + fieldConfAnnot.key(), field.getType(), hints));
+ } else if (Collection.class.isAssignableFrom(field.getType())) {
+ Object obj = get(tenant, namespace, keyPrefix + fieldConfAnnot.key(),
+ ConfigurationUtils.getArrayClass(ConfigurationUtils.getCollectionGenericType(field)),
+ hints);
+ if (obj != null) {
+ List list = Arrays.asList((Object[]) obj);
+ Class clazzToInstantiate = null;
+ if (field.getType().isInterface()) {
+ clazzToInstantiate =
+ ConfigurationUtils.getConcreteCollection(field.getType()).getClass();
+ } else if (Modifier.isAbstract(field.getType().getModifiers())) {
+ clazzToInstantiate =
+ ConfigurationUtils.getCompatibleCollectionForAbstractDef(field.getType())
+ .getClass();
+ } else {
+ clazzToInstantiate = field.getType();
+ }
+ Constructor construct =
+ getConstructorWithArguments(clazzToInstantiate, Collection.class);
+ if (construct != null) {
+ construct.setAccessible(true);
+ field.set(objToReturn, construct.newInstance(list));
+ } else if ((construct =
+ getConstructorWithArguments(clazzToInstantiate, Integer.class, Boolean.class,
+ Collection.class)) != null) {
+ construct.setAccessible(true);
+ field.set(objToReturn, construct.newInstance(list.size(), true, list));
+ }
+ }
+ }else if (Map.class.isAssignableFrom(field.getType())){
+ field.set(objToReturn, generateMap(tenant, namespace, keyPrefix+fieldConfAnnot.key()));
+ }
+ }
+ }
+ return objToReturn;
+ }
+
+ private Constructor getConstructorWithArguments(Class clazz, Class... classes) {
+ try {
+ return clazz.getDeclaredConstructor(classes);
+ } catch (Exception exception) {
+ return null;
+ }
+ }
+
+ private Class getWrapperClass(Class clazz) {
+ if (byte.class == clazz) {
+ return Byte.class;
+ } else if (short.class == clazz) {
+ return Short.class;
+ } else if (int.class == clazz) {
+ return Integer.class;
+ } else if (long.class == clazz) {
+ return Long.class;
+ } else if (float.class == clazz) {
+ return Float.class;
+ } else if (double.class == clazz) {
+ return Double.class;
+ } else if (char.class == clazz) {
+ return Character.class;
+ } else if (boolean.class == clazz) {
+ return Boolean.class;
+ }
+ return clazz;
+ }
+
+ private <T> T getValue(Object obj, Class<T> clazz, int processingHint) {
+ if (obj == null || obj.toString().trim().length() == 0) {
+ return null;
+ } else {
+ obj = obj.toString().trim();
+ }
+ if (String.class.equals(clazz)) {
+ if (obj.toString().startsWith("@") && ConfigurationUtils.isExternalLookup(processingHint)) {
+ String contents = ConfigurationUtils
+ .getFileContents(NonConfigResource.locate(obj.toString().substring(1).trim()));
+ if (contents == null) {
+ contents = ConfigurationUtils.getFileContents(obj.toString().substring(1).trim());
+ }
+ if (contents != null) {
+ obj = contents;
+ }
+ }
+ return (T) obj.toString();
+ } else if (Number.class.isAssignableFrom(clazz)) {
+ Double doubleValue = Double.valueOf(obj.toString());
+ switch (clazz.getName()) {
+ case "java.lang.Byte":
+ Byte byteVal = doubleValue.byteValue();
+ return (T) byteVal;
+ case "java.lang.Short":
+ Short shortVal = doubleValue.shortValue();
+ return (T) shortVal;
+ case "java.lang.Integer":
+ Integer intVal = doubleValue.intValue();
+ return (T) intVal;
+ case "java.lang.Long":
+ Long longVal = doubleValue.longValue();
+ return (T) longVal;
+ case "java.lang.Float":
+ Float floatVal = doubleValue.floatValue();
+ return (T) floatVal;
+ case "java.lang.Double":
+ Double doubleVal = doubleValue.doubleValue();
+ return (T) doubleVal;
+ default:
+ }
+ } else if (Boolean.class.equals(clazz)) {
+ return (T) Boolean.valueOf(obj.toString());
+ } else if (Character.class.equals(clazz)) {
+ return (T) Character.valueOf(obj.toString().charAt(0));
+ }
+ return null;
+ }
+
+ private <T> T[] getZeroLengthArrayFor(Class<T> clazz) {
+ Object obj = null;
+ if (clazz == int.class) {
+ obj = new int[]{};
+ } else if (clazz == byte.class) {
+ obj = new byte[]{};
+ } else if (clazz == short.class) {
+ obj = new short[]{};
+ } else if (clazz == long.class) {
+ obj = new long[]{};
+ } else if (clazz == float.class) {
+ obj = new float[]{};
+ } else if (clazz == double.class) {
+ obj = new double[]{};
+ } else if (clazz == boolean.class) {
+ obj = new boolean[]{};
+ } else if (clazz == char.class) {
+ obj = new char[]{};
+ } else if (clazz == Byte.class) {
+ obj = new Byte[]{};
+ } else if (clazz == Short.class) {
+ obj = new Short[]{};
+ } else if (clazz == Integer.class) {
+ obj = new Integer[]{};
+ } else if (clazz == Long.class) {
+ obj = new Long[]{};
+ } else if (clazz == Float.class) {
+ obj = new Float[]{};
+ } else if (clazz == Double.class) {
+ obj = new Double[]{};
+ } else if (clazz == Boolean.class) {
+ obj = new Boolean[]{};
+ } else if (clazz == Character.class) {
+ obj = new Character[]{};
+ } else if (clazz == String.class) {
+ obj = new String[]{};
+ }
+ return (T[]) obj;
+ }
+
+ private <T> Collection<T> convert(String commaSaperatedValues, Class<T> clazz,
+ int processingHints) {
+ ArrayList<T> collection = new ArrayList<>();
+ for (String value : commaSaperatedValues.split(",")) {
+ try {
+ T type1 = getValue(value, clazz, processingHints);
+ if (type1 != null) {
+ collection.add(type1);
+ }
+ } catch (RuntimeException re) {
+ // do nothing
+ }
+ }
+ return collection;
+ }
+
+ /**
+ * Shutdown.
+ */
+ public void shutdown() {
+ if (changeNotifier != null) {
+ try {
+ changeNotifier.shutdown();
+ ConfigurationDataSource.lookup().close();
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ }
+ }
+
+ @Override
+ public void removeConfigurationChangeListener(String tenant, String namespace, String key,
+ ConfigurationChangeListener myself) {
+ tenant = ConfigurationRepository.lookup().isValidTenant(tenant) ? tenant.toUpperCase()
+ : Constants.DEFAULT_TENANT;
+ namespace =
+ ConfigurationRepository.lookup().isValidNamespace(namespace) ? namespace.toUpperCase()
+ : Constants.DEFAULT_NAMESPACE;
+ if (key == null || key.trim().length() == 0) {
+ throw new IllegalArgumentException("Key can't be null.");
+ }
+ try {
+ changeNotifier.stopNotificationTowards(tenant, namespace, key, myself);
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ }
+
+ @Override
+ public <T> Map<String, T> populateMap(String tenantId, String namespace, String key, Class<T> clazz){
+ if (tenantId==null || tenantId.trim().length()==0){
+ tenantId = this.tenant.get();
+ }else{
+ tenantId = tenantId.toUpperCase();
+ }
+ if (namespace==null || namespace.trim().length()==0){
+ namespace = Constants.DEFAULT_NAMESPACE;
+ }else{
+ namespace = namespace.toUpperCase();
+ }
+ Map<String, T> map = new HashMap<>();
+ Iterator<String> keys ;
+ try {
+ if (ConfigurationRepository.lookup().isDBAccessible()){
+ keys = ConfigurationUtils.executeSelectSql(ConfigurationRepository.lookup().getConfigurationFor(
+ Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE).getString("fetchkeysql"), new String[]{tenantId+ Constants.KEY_ELEMENTS_DELEMETER+namespace}).iterator();
+ }else{
+ keys = ConfigurationRepository.lookup().getConfigurationFor(tenantId, namespace).getKeys(key);
+ }
+ while(keys.hasNext()){
+ String k = keys.next();
+ if (k.startsWith(key+".")){
+ k = k.substring(key.length()+1);
+ String subkey = k.substring(0, k.indexOf("."));
+ if (!map.containsKey(subkey)){
+ map.put(subkey, get(tenantId, namespace, key+"."+subkey, clazz));
+ }
+ }
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ return map;
+ }
+
+ @Override
+ public Map generateMap(String tenantId, String namespace, String key){
+ if (tenantId==null || tenantId.trim().length()==0){
+ tenantId = this.tenant.get();
+ }else{
+ tenantId = tenantId.toUpperCase();
+ }
+ if (namespace==null || namespace.trim().length()==0){
+ namespace = Constants.DEFAULT_NAMESPACE;
+ }else{
+ namespace = namespace.toUpperCase();
+ }
+ Map map, parentMap = new HashMap<>();
+ Iterator<String> keys ;
+ try {
+ if (ConfigurationRepository.lookup().isDBAccessible()){
+ keys = ConfigurationUtils.executeSelectSql(ConfigurationRepository.lookup().getConfigurationFor(
+ Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE).getString("fetchkeysql"), new String[]{tenantId+ Constants.KEY_ELEMENTS_DELEMETER+namespace}).iterator();
+ }else{
+ if (key==null || key.trim().length()==0){
+ keys = ConfigurationRepository.lookup().getConfigurationFor(tenantId, namespace).getKeys();
+ }else{
+ keys = ConfigurationRepository.lookup().getConfigurationFor(tenantId, namespace).getKeys(key);
+ }
+ }
+ while(keys.hasNext()){
+ map = parentMap;
+ String k = keys.next();
+
+ if (key!=null && key.trim().length()!=0 && !k.startsWith(key+".")){
+ continue;
+ }
+ String value = getAsString(tenantId, namespace, k);
+ if (key!=null && key.trim().length()!=0 && k.startsWith(key+".")){
+ k = k.substring(key.trim().length()+1);
+ }
+
+ while(k.contains(".")){
+ if (k.contains(".")){
+ String subkey = k.substring(0, k.indexOf("."));
+ k = k.substring(k.indexOf(".")+1);
+ if (!map.containsKey(subkey)){
+ map.put(subkey, map=new HashMap<>());
+ }else{
+ map = (Map)map.get(subkey);
+ }
+ }
+ }
+ map.put(k, value);
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ return parentMap;
+ }
+
+
+
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationRepository.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationRepository.java
new file mode 100644
index 0000000000..1c3bc1313f
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationRepository.java
@@ -0,0 +1,415 @@
+package org.onap.config.impl;
+
+import org.apache.commons.configuration2.CombinedConfiguration;
+import org.apache.commons.configuration2.CompositeConfiguration;
+import org.apache.commons.configuration2.Configuration;
+import org.apache.commons.configuration2.FileBasedConfiguration;
+import org.apache.commons.configuration2.builder.BasicConfigurationBuilder;
+import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
+import org.apache.commons.configuration2.ex.ConfigurationException;
+import org.onap.config.ConfigurationUtils;
+import org.onap.config.Constants;
+
+import java.io.File;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The type Configuration repository.
+ */
+public final class ConfigurationRepository {
+
+ /**
+ * The Repo.
+ */
+ static ConfigurationRepository repo;
+ private static Set<String> validCallers = Collections.unmodifiableSet(new HashSet<>(Arrays
+ .asList(ConfigurationChangeNotifier.NotificationData.class.getName(),
+ ConfigurationUtils.class.getName(), CliConfigurationImpl.class.getName(),
+ ConfigurationChangeNotifier.class.getName(), ConfigurationDataSource.class.getName(),
+ ConfigurationImpl.class.getName())));
+
+ static {
+ repo = new ConfigurationRepository();
+ }
+
+ private boolean dbAccessible = true;
+ private Set<String> tenants = new HashSet<>();
+ private Set<String> namespaces = new HashSet<>();
+ private LinkedHashMap<String, ConfigurationHolder> store =
+ new LinkedHashMap<String, ConfigurationHolder>(16, 0.75f, true) {
+ @Override
+ protected boolean removeEldestEntry(Map.Entry eldest) {
+ try {
+ return size() > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
+ .getInt("config.size.max");
+ } catch (Exception exception) {
+ return false;
+ }
+ }
+ };
+
+ private ConfigurationRepository() {
+ if (repo != null) {
+ throw new RuntimeException("Illegal access to configuration.");
+ }
+ tenants.add(Constants.DEFAULT_TENANT);
+ namespaces.add(Constants.DEFAULT_NAMESPACE);
+ }
+
+ /**
+ * Lookup configuration repository.
+ *
+ * @return the configuration repository
+ */
+ public static ConfigurationRepository lookup() {
+ if (validCallers.contains(Thread.currentThread().getStackTrace()[2].getClassName())) {
+ return repo;
+ }
+ return null;
+ }
+
+ /**
+ * Gets tenants.
+ *
+ * @return the tenants
+ */
+ public Set<String> getTenants() {
+ return tenants;
+ }
+
+ /**
+ * Gets namespaces.
+ *
+ * @return the namespaces
+ */
+ public Set<String> getNamespaces() {
+ return namespaces;
+ }
+
+ private void populateTenantsNamespace(String key, boolean sourcedFromDb) {
+ String[] array = key.split(Constants.KEY_ELEMENTS_DELEMETER);
+ if (!array[1].equalsIgnoreCase(Constants.DB_NAMESPACE)) {
+ if (!sourcedFromDb) {
+ dbAccessible = false;
+ }
+ tenants.add(array[0]);
+ namespaces.add(array[1]);
+ }
+ }
+
+ /**
+ * Init tenants and namespaces.
+ */
+ public void initTenantsAndNamespaces() {
+ try {
+ Collection<String> collection = ConfigurationUtils.executeSelectSql(
+ getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
+ .getString("fetchnamescql"), new String[]{});
+ Iterator<String> iterator = collection.iterator();
+ while (iterator.hasNext()) {
+ populateTenantsNamespace(iterator.next(), true);
+ }
+ } catch (Exception exception) {
+ //Log this later
+ }
+ }
+
+ /**
+ * Is valid tenant boolean.
+ *
+ * @param tenant the tenant
+ * @return the boolean
+ */
+ public boolean isValidTenant(String tenant) {
+ return tenant == null ? false : tenants.contains(tenant.toUpperCase());
+ }
+
+ /**
+ * Is valid namespace boolean.
+ *
+ * @param namespace the namespace
+ * @return the boolean
+ */
+ public boolean isValidNamespace(String namespace) {
+ return namespace == null ? false : namespaces.contains(namespace.toUpperCase());
+ }
+
+ /**
+ * Gets configuration for.
+ *
+ * @param tenant the tenant
+ * @param namespace the namespace
+ * @return the configuration for
+ * @throws Exception the exception
+ */
+ public Configuration getConfigurationFor(String tenant, String namespace) throws Exception {
+ ConfigurationHolder config;
+ String module = tenant + Constants.KEY_ELEMENTS_DELEMETER + namespace;
+ config = store.get(module);
+ if (config == null) {
+ config = new ConfigurationHolder(ConfigurationUtils
+ .getDbConfigurationBuilder(tenant + Constants.KEY_ELEMENTS_DELEMETER + namespace));
+ store.put(module, config);
+ }
+ return config.getConfiguration(tenant + Constants.KEY_ELEMENTS_DELEMETER + namespace);
+ }
+
+ /**
+ * Populate configurtaion.
+ *
+ * @param key the key
+ * @param builder the builder
+ */
+ public void populateConfigurtaion(String key, Configuration builder) {
+ store.put(key, new ConfigurationHolder(builder));
+ populateTenantsNamespace(key, false);
+ }
+
+ /**
+ * Populate configurtaion.
+ *
+ * @param key the key
+ * @param builder the builder
+ * @throws Exception the exception
+ */
+ public void populateConfigurtaion(String key, BasicConfigurationBuilder builder)
+ throws Exception {
+ store.put(key, new ConfigurationHolder(builder));
+ }
+
+ /**
+ * Populate override configurtaion.
+ *
+ * @param key the key
+ * @param file the file
+ * @throws Exception the exception
+ */
+ public void populateOverrideConfigurtaion(String key, File file) throws Exception {
+ ConfigurationHolder holder = store.get(key);
+ if (holder == null) {
+ if (dbAccessible) {
+ holder = new ConfigurationHolder(ConfigurationUtils.getDbConfigurationBuilder(key));
+ } else {
+ holder = new ConfigurationHolder(new CombinedConfiguration());
+ }
+ store.put(key, holder);
+ }
+ holder.addOverrideConfiguration(file.getAbsolutePath(),
+ ConfigurationUtils.getConfigurationBuilder(file, true));
+ populateTenantsNamespace(key, true);
+ }
+
+ /**
+ * Refresh override configurtaion for.
+ *
+ * @param key the key
+ * @param index the index
+ * @throws Exception the exception
+ */
+ public void refreshOverrideConfigurtaionFor(String key, int index) throws Exception {
+ ConfigurationHolder holder = store.get(key);
+ if (holder != null) {
+ holder.refreshOverrideConfiguration(index);
+ }
+ }
+
+ /**
+ * Remove override configurtaion.
+ *
+ * @param file the file
+ * @throws Exception the exception
+ */
+ public void removeOverrideConfigurtaion(File file) throws Exception {
+ Iterator<String> iterator = new ArrayList(store.keySet()).iterator();
+ while (iterator.hasNext()) {
+ ConfigurationHolder holder = store.get(iterator.next());
+ if (holder.containsOverrideConfiguration(file.getAbsolutePath())) {
+ holder.removeOverrideConfiguration(file.getAbsolutePath());
+ }
+ }
+
+ }
+
+ private class ConfigurationHolder {
+
+ /**
+ * The Builder.
+ */
+ BasicConfigurationBuilder<Configuration> builder;
+ /**
+ * The Last configuration build time.
+ */
+ Timestamp lastConfigurationBuildTime;
+ /**
+ * The Config.
+ */
+ Configuration config;
+ /**
+ * The Composite.
+ */
+ Configuration composite;
+ /**
+ * The Last config change timestamp.
+ */
+ Timestamp lastConfigChangeTimestamp;
+ private Map<String, FileBasedConfigurationBuilder<FileBasedConfiguration>>
+ overrideConfiguration = new LinkedHashMap<>();
+
+
+ /**
+ * Instantiates a new Configuration holder.
+ *
+ * @param builder the builder
+ */
+ public ConfigurationHolder(BasicConfigurationBuilder builder) {
+ this.builder = builder;
+ }
+
+ /**
+ * Instantiates a new Configuration holder.
+ *
+ * @param builder the builder
+ */
+ public ConfigurationHolder(Configuration builder) {
+ this.config = builder;
+ }
+
+ /**
+ * Refresh override configuration.
+ *
+ * @param index the index
+ */
+ public void refreshOverrideConfiguration(int index) {
+ int count = -1;
+ for (FileBasedConfigurationBuilder overrides : overrideConfiguration.values()) {
+ try {
+ if (++count == index) {
+ overrides.save();
+ overrides.resetResult();
+ }
+ } catch (ConfigurationException exception) {
+ //do nothing
+ }
+ }
+ }
+
+ /**
+ * Add override configuration.
+ *
+ * @param path the path
+ * @param builder the builder
+ */
+ public void addOverrideConfiguration(String path,
+ BasicConfigurationBuilder<FileBasedConfiguration> builder) {
+ overrideConfiguration.put(path.toUpperCase(), (FileBasedConfigurationBuilder) builder);
+ getEffectiveConfiguration(config, overrideConfiguration.values());
+ }
+
+ /**
+ * Remove override configuration.
+ *
+ * @param path the path
+ */
+ public void removeOverrideConfiguration(String path) {
+ overrideConfiguration.remove(path.toUpperCase());
+ getEffectiveConfiguration(config, overrideConfiguration.values());
+ }
+
+ /**
+ * Contains override configuration boolean.
+ *
+ * @param path the path
+ * @return the boolean
+ */
+ public boolean containsOverrideConfiguration(String path) {
+ return overrideConfiguration.containsKey(path.toUpperCase());
+ }
+
+ /**
+ * Gets configuration.
+ *
+ * @param namespace the namespace
+ * @return the configuration
+ * @throws Exception the exception
+ */
+ public Configuration getConfiguration(String namespace) throws Exception {
+ if (config == null) {
+ config = builder.getConfiguration();
+ lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
+ } else if (lastConfigurationBuildTime != null
+ && System.currentTimeMillis() - lastConfigurationBuildTime.getTime()
+ > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
+ .getInt("config.refresh.interval")) {
+ Timestamp temp = getLastUpdateTimestampFor(namespace);
+ if ((temp != null)
+ && (lastConfigChangeTimestamp == null
+ || temp.getTime() > lastConfigChangeTimestamp.getTime())) {
+ builder.resetResult();
+ config = builder.getConfiguration();
+ lastConfigChangeTimestamp = temp;
+ getEffectiveConfiguration(config, overrideConfiguration.values());
+ }
+ lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
+ }
+ if (composite == null && overrideConfiguration.size() != 0) {
+ composite = getEffectiveConfiguration(config, overrideConfiguration.values());
+ }
+ return overrideConfiguration.size() == 0 ? config : composite;
+ }
+
+ private Configuration getEffectiveConfiguration(Configuration configuration,
+ Collection<FileBasedConfigurationBuilder<FileBasedConfiguration>> list) {
+ try {
+ CompositeConfiguration cc = new CompositeConfiguration();
+ for (FileBasedConfigurationBuilder<FileBasedConfiguration> b : list) {
+ cc.addConfiguration(b.getConfiguration());
+ }
+ cc.addConfiguration(configuration);
+ composite = cc;
+ return composite;
+ } catch (Exception exception) {
+ return null;
+ }
+ }
+
+ /**
+ * Gets last update timestamp for.
+ *
+ * @param namespace the namespace
+ * @return the last update timestamp for
+ */
+ public Timestamp getLastUpdateTimestampFor(String namespace) {
+ Timestamp timestamp = null;
+
+ try {
+ Collection<String> collection = ConfigurationUtils.executeSelectSql(
+ getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
+ .getString("fetchlastchangecql"), new String[]{namespace});
+ if (!collection.isEmpty()) {
+ timestamp = new Timestamp(Long.valueOf(((ArrayList) collection).get(0).toString()));
+ }
+ } catch (Exception exception) {
+ //Log this later
+ }
+
+ return timestamp;
+ }
+
+
+ }
+
+ public boolean isDBAccessible(){
+ return dbAccessible;
+ }
+
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ContextListener.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ContextListener.java
new file mode 100644
index 0000000000..cf87db936d
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ContextListener.java
@@ -0,0 +1,28 @@
+package org.onap.config.impl;
+
+import static org.onap.config.Constants.MBEAN_NAME;
+
+import java.lang.management.ManagementFactory;
+import javax.management.ObjectName;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.annotation.WebListener;
+import org.onap.config.api.ConfigurationManager;
+
+@WebListener
+public class ContextListener implements ServletContextListener {
+
+ @Override
+ public void contextDestroyed(ServletContextEvent arg0) {
+ try {
+ ManagementFactory.getPlatformMBeanServer().unregisterMBean(new ObjectName(MBEAN_NAME));
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ }
+
+ @Override
+ public void contextInitialized(ServletContextEvent arg0) {
+ ConfigurationManager.lookup();
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/YamlConfiguration.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/YamlConfiguration.java
new file mode 100644
index 0000000000..dc6785fd73
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/YamlConfiguration.java
@@ -0,0 +1,18 @@
+package org.onap.config.impl;
+
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+import com.virtlink.commons.configuration2.jackson.JacksonConfiguration;
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.tree.ImmutableNode;
+
+public class YamlConfiguration extends JacksonConfiguration {
+
+ protected YamlConfiguration(HierarchicalConfiguration<ImmutableNode> config) {
+ super(new YAMLFactory(), config);
+ }
+
+ public YamlConfiguration() {
+ super(new YAMLFactory());
+ }
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationMode.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationMode.java
new file mode 100644
index 0000000000..826d53e6bc
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationMode.java
@@ -0,0 +1,5 @@
+package org.onap.config.type;
+
+public enum ConfigurationMode {
+ OVERRIDE, UNION, MERGE
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationQuery.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationQuery.java
new file mode 100644
index 0000000000..6aec7c27da
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationQuery.java
@@ -0,0 +1,94 @@
+package org.onap.config.type;
+
+import org.onap.config.Constants;
+
+public class ConfigurationQuery {
+
+ String tenant = Constants.DEFAULT_TENANT;
+ String namespace = Constants.DEFAULT_NAMESPACE;
+ String key;
+ boolean fallback;
+ boolean externalLookup;
+ boolean latest;
+ private boolean nodeSpecific;
+
+ public ConfigurationQuery fallback(boolean fallback) {
+ this.fallback = fallback;
+ return this;
+ }
+
+ public ConfigurationQuery latest(boolean val) {
+ this.latest = val;
+ return this;
+ }
+
+ public ConfigurationQuery nodeSpecific(boolean val) {
+ this.nodeSpecific = val;
+ return this;
+ }
+
+ public ConfigurationQuery externalLookup(boolean val) {
+ this.externalLookup = val;
+ return this;
+ }
+
+ /**
+ * Tenant configuration query.
+ *
+ * @param id the id
+ * @return the configuration query
+ */
+ public ConfigurationQuery tenant(String id) {
+ if (id != null) {
+ tenant = id;
+ }
+ return this;
+ }
+
+
+ /**
+ * Namespace configuration query.
+ *
+ * @param id the id
+ * @return the configuration query
+ */
+ public ConfigurationQuery namespace(String id) {
+ if (id != null) {
+ namespace = id;
+ }
+ return this;
+ }
+
+ public ConfigurationQuery key(String id) {
+ key = id;
+ return this;
+ }
+
+ public String getTenant() {
+ return tenant.toUpperCase();
+ }
+
+ public String getNamespace() {
+ return namespace.toUpperCase();
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public boolean isFallback() {
+ return fallback;
+ }
+
+ public boolean isNodeSpecific() {
+ return nodeSpecific;
+ }
+
+ public boolean isExternalLookup() {
+ return externalLookup;
+ }
+
+ public boolean isLatest() {
+ return latest;
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationType.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationType.java
new file mode 100644
index 0000000000..54253fa754
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationType.java
@@ -0,0 +1,5 @@
+package org.onap.config.type;
+
+public enum ConfigurationType {
+ PROPERTIES, XML, JSON, YAML
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationUpdate.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationUpdate.java
new file mode 100644
index 0000000000..739dd776bf
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/type/ConfigurationUpdate.java
@@ -0,0 +1,33 @@
+package org.onap.config.type;
+
+public class ConfigurationUpdate extends ConfigurationQuery {
+ private String value;
+ private boolean nodeOverride;
+
+ public ConfigurationUpdate value(String val) {
+ value = val;
+ return this;
+ }
+
+ public ConfigurationUpdate nodeOverride(boolean val) {
+ nodeOverride = val;
+ return this;
+ }
+
+ /**
+ * Gets value.
+ *
+ * @return the value
+ */
+ public String getValue() {
+ if (value != null && value.split(",").length > 1 && !value.matches("^\\[.*\\]$")) {
+ return "[" + value + "]";
+ }
+ return value;
+ }
+
+ public boolean isNodeOverride() {
+ return nodeOverride;
+ }
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/resources/META-INF/services/org.onap.config.api.ConfigurationManager b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/resources/META-INF/services/org.onap.config.api.ConfigurationManager
new file mode 100644
index 0000000000..173484f1a7
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/resources/META-INF/services/org.onap.config.api.ConfigurationManager
@@ -0,0 +1 @@
+org.onap.config.impl.CliConfigurationImpl \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/resources/config-system.properties b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/resources/config-system.properties
new file mode 100644
index 0000000000..cfe91e6c7d
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/resources/config-system.properties
@@ -0,0 +1,22 @@
+driverClassName=com.github.adejanovski.cassandra.jdbc.CassandraDriver
+jdbcURL=jdbc:${dbname}://${dbhost}:${dbport}/${configdb}
+dbuser=
+dbpassword=
+config.Table=configuration
+config.monitor.Table=configuration_change
+configKey=key
+configValue=value
+configNameColumn=name
+configdb=dox
+dbhost=
+dbport=9042
+dbname=cassandra
+createtablecql=create table if not exists ${configdb}.${config.Table} (name text\, key text\, value text\, PRIMARY KEY (name\, key)) with clustering order by (key asc)
+createmonitoringtablecql=create table if not exists ${configdb}.${config.monitor.Table} (name text\, changed_when bigint\, key text\, old_value text\, new_value text\, PRIMARY KEY (name\, changed_when)) with clustering order by (changed_when desc)
+insertconfigurationchangecql=insert into ${configdb}.${config.monitor.Table} (name\, changed_when\, key\, old_value\, new_value) values(?\, ?\, ?\, ?\, ?)
+fetchkeysql=select ${configKey} from ${config.Table} where ${configNameColumn}=?
+fetchlastchangecql=select changed_when from ${configdb}.${config.monitor.Table} where name=? limit 1
+fetchnamescql=select distinct name from ${configdb}.${config.Table}
+config.size.max=100
+config.refresh.interval=30000
+event.fetch.delay=5000 \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/resources/management.properties b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/resources/management.properties
new file mode 100644
index 0000000000..9874394726
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/resources/management.properties
@@ -0,0 +1,7 @@
+com.sun.management.jmxremote=true
+#com.sun.management.jmxremote.port=9999
+#com.sun.management.jmxremote.local.only=false
+#com.sun.management.jmxremote.authenticate=false
+#com.sun.management.jmxremote.password.file=resources/jmxremote.password
+#com.sun.management.jmxremote.access.file=resources/jmxremote.access
+#com.sun.management.jmxremote.ssl=false \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/test/java/org/onap/config/ConfigurationUtilsTest.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/test/java/org/onap/config/ConfigurationUtilsTest.java
new file mode 100644
index 0000000000..90966fccf6
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/test/java/org/onap/config/ConfigurationUtilsTest.java
@@ -0,0 +1,32 @@
+package org.onap.config;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class ConfigurationUtilsTest {
+ @Test
+ public void testCommaList() {
+ List list = Arrays.asList("1", "2", 3);
+ String commaSeparatedList = ConfigurationUtils.getCommaSeparatedList(list);
+ list.forEach(o -> assertTrue(commaSeparatedList.contains(o.toString())));
+ }
+
+ @Test
+ public void testCommaListWithNullAndEmptyStrings() {
+ List list = Arrays.asList(null, "", " ");
+ String commaSeparatedList = ConfigurationUtils.getCommaSeparatedList(list);
+ assertTrue(commaSeparatedList.isEmpty());
+ }
+
+ @Test
+ public void testGetArrayClassFunction() {
+ assertEquals(String[].class , ConfigurationUtils.getArrayClass(String.class));
+ assertNull(ConfigurationUtils.getArrayClass(ConfigurationUtilsTest.class));
+ }
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/pom.xml b/common/onap-common-configuration-management/onap-configuration-management-test/pom.xml
new file mode 100644
index 0000000000..b9ce6a8cbc
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/pom.xml
@@ -0,0 +1,84 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <name>onap-configuration-management-test</name>
+ <groupId>org.onap.sdc.common</groupId>
+ <artifactId>onap-configuration-management-test</artifactId>
+
+ <parent>
+ <artifactId>onap-common-configuration-management</artifactId>
+ <groupId>org.onap.sdc.common</groupId>
+ <version>1.2.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.sdc.common</groupId>
+ <artifactId>onap-configuration-management-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <!-- <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin-->
+ <!--<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${mvn.surefire.version}</version>
+ </plugin>-->
+ <!-- any other plugins -->
+ <!-- <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>${mvn.shade.version}</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <artifactSet>
+ <excludes>
+ <exclude>com.google.guava:*</exclude>
+ </excludes>
+ </artifactSet>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>-->
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${mvn.surefire.version}</version>
+ <configuration>
+ <skipTests>true</skipTests>
+ <systemPropertyVariables>
+ <config.location>${project.basedir}/src/test/resources</config.location>
+ <node.config.location>${user.home}/TestResources</node.config.location>
+ </systemPropertyVariables>
+ <includes>
+ <include>**/TestCMSuite.java</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/TestCMSuite.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/TestCMSuite.java
new file mode 100644
index 0000000000..de265c7281
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/TestCMSuite.java
@@ -0,0 +1,76 @@
+package org.onap.config;
+
+import org.onap.config.test.CLIFallbackAndLookupTest;
+import org.onap.config.test.CLITest;
+import org.onap.config.test.ConfigSourceLocationTest;
+import org.onap.config.test.DynamicConfigurationTest;
+import org.onap.config.test.FallbackConfigTest;
+import org.onap.config.test.FallbackToGlobalNSTest;
+import org.onap.config.test.GlobalAndNSConfigTest;
+import org.onap.config.test.JAVAPropertiesConfigTest;
+import org.onap.config.test.JSONConfigTest;
+import org.onap.config.test.LoadOrderMergeAndOverrideTest;
+import org.onap.config.test.ModeAsConfigPropTest;
+import org.onap.config.test.MultiTenancyConfigTest;
+import org.onap.config.test.NodeSpecificCLITest;
+import org.onap.config.test.NotificationForNodeConfigTest;
+import org.onap.config.test.NotificationOnPropValTest;
+import org.onap.config.test.ResourceChangeNotificationTest;
+import org.onap.config.test.UnregisterNotificationTest;
+import org.onap.config.test.ValidateDefaultModeTest;
+import org.onap.config.test.ValidateNodeConfigTest;
+import org.onap.config.test.XMLConfigTest;
+import org.onap.config.test.YAMLConfigTest;
+import org.onap.config.test.*;
+import org.junit.AfterClass;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Created by sheetalm on 10/25/2016.
+ */
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ JAVAPropertiesConfigTest.class,
+ JSONConfigTest.class,
+ XMLConfigTest.class,
+ YAMLConfigTest.class,
+ CLIFallbackAndLookupTest.class,
+ CLITest.class,
+ ConfigSourceLocationTest.class,
+ DynamicConfigurationTest.class,
+ FallbackConfigTest.class,
+ FallbackToGlobalNSTest.class,
+ GlobalAndNSConfigTest.class,
+ ModeAsConfigPropTest.class,
+ MultiTenancyConfigTest.class,
+ NodeSpecificCLITest.class,
+ NotificationForNodeConfigTest.class,
+ NotificationOnPropValTest.class,
+ ResourceChangeNotificationTest.class,
+ UnregisterNotificationTest.class,
+ ValidateDefaultModeTest.class,
+ ValidateNodeConfigTest.class,
+ LoadOrderMergeAndOverrideTest.class
+
+
+})
+
+public class TestCMSuite extends junit.framework.TestSuite {
+
+ private TestCMSuite() {
+
+ }
+
+ @AfterClass
+ public static void tearDown(){
+ try {
+ ConfigurationUtils.executeDdlSql("truncate dox.configuration_change");
+ ConfigurationUtils.executeDdlSql("truncate dox.configuration");
+ }
+ catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/CLIFallbackAndLookupTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/CLIFallbackAndLookupTest.java
new file mode 100644
index 0000000000..f4598be0d0
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/CLIFallbackAndLookupTest.java
@@ -0,0 +1,83 @@
+package org.onap.config.test;
+
+import org.onap.config.util.ConfigTestConstant;
+import org.onap.config.Constants;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.util.TestUtil;
+import org.junit.Assert;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.management.JMX;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.HashMap;
+import java.util.Map;
+
+
+
+/**
+ * Created by sheetalm on 10/18/2016.
+ * Scenario 21, Scenario 23
+ * 21 - Verify the CLI fetches only the current value unless the fallback option is specified
+ * 23 - Fetch value using CLI for a key with underlying resource
+ */
+public class CLIFallbackAndLookupTest {
+
+ public final static String NAMESPACE = "CLIFallback";
+ public final static String TENANT = "OPENECOMP";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ TestUtil.writeFile(data);
+ }
+
+ @Test
+ public void testCLIFallbackAndLookup() throws Exception{
+
+ //Verify without fallback
+ Map<String, Object> input = new HashMap<>();
+ input.put("ImplClass", "org.openecomp.config.type.ConfigurationQuery");
+ input.put("tenant", TENANT);
+ input.put("namespace", NAMESPACE);
+ input.put("key", ConfigTestConstant.ARTIFACT_MAXSIZE);
+
+ MBeanServerConnection mbsc = ManagementFactory.getPlatformMBeanServer();
+ ObjectName mbeanName = new ObjectName(Constants.MBEAN_NAME);
+ ConfigurationManager conf = JMX.newMBeanProxy(mbsc, mbeanName, ConfigurationManager.class, true);
+ String maxSizeWithNoFallback = conf.getConfigurationValue(input);
+ Assert.assertEquals("",maxSizeWithNoFallback);
+
+ //Verify underlying resource without lookup switch
+ input.put("key", ConfigTestConstant.ARTIFACT_JSON_SCHEMA);
+ String jsonSchema = conf.getConfigurationValue(input);
+ System.out.println("jsonSchema=="+jsonSchema);
+ Assert.assertEquals("@"+System.getProperty("user.home")+"/TestResources/GeneratorsList.json" , jsonSchema);
+
+ //Verify underlying resource with lookup switch
+ input.put("externalLookup", true);
+ jsonSchema = conf.getConfigurationValue(input);
+ System.out.println("jsonSchema=="+jsonSchema);
+ Assert.assertEquals("{name:\"SCM\"}" , jsonSchema);
+
+ //Verify with fallback
+ Map<String, Object> fallbackInput = new HashMap<>();
+ fallbackInput.put("ImplClass", "org.openecomp.config.type.ConfigurationQuery");
+ fallbackInput.put("fallback", true);
+ fallbackInput.put("tenant", TENANT);
+ fallbackInput.put("namespace", NAMESPACE);
+ fallbackInput.put("key", ConfigTestConstant.ARTIFACT_MAXSIZE);
+
+ String maxSizeWithFallback = conf.getConfigurationValue(fallbackInput);
+ Assert.assertEquals("1024",maxSizeWithFallback);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/CLITest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/CLITest.java
new file mode 100644
index 0000000000..5a3f39fd16
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/CLITest.java
@@ -0,0 +1,108 @@
+package org.onap.config.test;
+
+import org.onap.config.util.ConfigTestConstant;
+import org.onap.config.Constants;
+import org.onap.config.api.ConfigurationChangeListener;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.management.JMX;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by sheetalm on 10/18/2016.
+ * Scenario 17
+ * Verify Configuration Management System - Command Line Interface for query, update and list operations
+ */
+public class CLITest {
+
+ public final static String NAMESPACE = "CLI";
+ public final static String TENANT = "OPENECOMP";
+ private String updatedValue = "";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ TestUtil.writeFile(data);
+ }
+
+ @Test
+ public void testCLIApi() throws Exception{
+ //Verify without fallback
+ Map<String, Object> input = new HashMap<>();
+ input.put("ImplClass", "org.openecomp.config.type.ConfigurationQuery");
+ input.put("tenant", TENANT);
+ input.put("namespace", NAMESPACE);
+ input.put("key", ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH);
+
+ MBeanServerConnection mbsc = ManagementFactory.getPlatformMBeanServer();
+ ObjectName mbeanName = new ObjectName(Constants.MBEAN_NAME);
+ ConfigurationManager conf = JMX.newMBeanProxy(mbsc, mbeanName, ConfigurationManager.class, true);
+ String maxLength = conf.getConfigurationValue(input);
+ Assert.assertEquals("14",maxLength);
+
+ conf.addConfigurationChangeListener(TENANT,NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH, new CLIListener());
+
+
+ //Update maxlength
+ input.put("ImplClass", "org.openecomp.config.type.ConfigurationUpdate");
+ input.put("value", "24");
+ conf.updateConfigurationValue(input);
+
+ Thread.sleep(35000);
+
+ Assert.assertEquals("24",updatedValue);
+
+ //Reset value and fetch updated value again
+ input.put("value", "");
+ input.put("ImplClass", "org.openecomp.config.type.ConfigurationQuery");
+ String updatedMaxLength = conf.getConfigurationValue(input);
+ Assert.assertEquals("24",updatedMaxLength);
+
+ Map<String, String> outputMap = conf.listConfiguration(input);
+ for(Map.Entry<String, String> entry : outputMap.entrySet()){
+ System.out.println(entry.getKey()+" : "+entry.getValue());
+ validateCLIListConfig(outputMap);
+ }
+ }
+
+ private class CLIListener implements ConfigurationChangeListener {
+ @Override
+ public void notify(String key, Object oldValue, Object newValue) {
+ System.out.println("received notification::oldValue=="+oldValue+" newValue=="+newValue);
+ updatedValue = newValue.toString();
+ }
+ }
+
+ private void validateCLIListConfig(Map<String, String> outputMap ) {
+
+ Assert.assertEquals("@"+System.getProperty("user.home")+"/TestResources/GeneratorsList.json" , outputMap.get(
+ ConfigTestConstant.ARTIFACT_JSON_SCHEMA));
+ Assert.assertEquals("appc,catalog", outputMap.get(ConfigTestConstant.ARTIFACT_CONSUMER));
+ Assert.assertEquals("6", outputMap.get(ConfigTestConstant.ARTIFACT_NAME_MINLENGTH));
+ Assert.assertEquals("true", outputMap.get(ConfigTestConstant.ARTIFACT_ENCODED));
+ Assert.assertEquals("24", outputMap.get(ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH));
+ Assert.assertEquals("pdf,zip,xml,pdf,tgz,xls", outputMap.get(ConfigTestConstant.ARTIFACT_EXT));
+ Assert.assertEquals("Base64,MD5", outputMap.get(ConfigTestConstant.ARTIFACT_ENC));
+ Assert.assertEquals("@"+System.getenv("Path")+"/myschema.json", outputMap.get(
+ ConfigTestConstant.ARTIFACT_XML_SCHEMA));
+ Assert.assertEquals("a-zA-Z_0-9", outputMap.get(ConfigTestConstant.ARTIFACT_NAME_UPPER));
+ Assert.assertEquals("/opt/spool,"+System.getProperty("user.home")+"/asdc", outputMap.get(
+ ConfigTestConstant.ARTIFACT_LOC));
+ Assert.assertEquals("deleted,Deleted", outputMap.get(ConfigTestConstant.ARTIFACT_STATUS));
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ConfigSourceLocationTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ConfigSourceLocationTest.java
new file mode 100644
index 0000000000..6751a5cc31
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ConfigSourceLocationTest.java
@@ -0,0 +1,53 @@
+package org.onap.config.test;
+
+import org.onap.config.api.Configuration;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.util.ConfigTestConstant;
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.Assert;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+import java.io.OutputStream;
+import java.io.FileOutputStream;
+
+/**
+ * Created by sheetalm on 10/14/2016.
+ * Scenario 11
+ * Validate conventional and configurational source location
+ *
+ * Pre-requisite - set -Dconfig.location=${"user.home"}/TestResources/ while running test
+ */
+public class ConfigSourceLocationTest {
+ public final static String NAMESPACE = "SourceLocation";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ TestUtil.writeFile(data);
+
+ Properties props = new Properties();
+ props.setProperty("maxCachedBufferSize", "1024");
+ props.setProperty("artifact.maxsize", "1024");
+ File f = new File(TestUtil.jsonSchemaLoc + "config.properties");
+ try (OutputStream out = new FileOutputStream(f)) {
+ props.store(out, "Config Property at Conventional Resource");
+ }
+ }
+
+ @Test
+ public void testMergeStrategyInConfig() throws IOException, InterruptedException {
+ Configuration config = ConfigurationManager.lookup();
+ Assert.assertEquals("a-zA-Z_0-9", config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_UPPER));
+ Assert.assertEquals("1024", config.getAsString(ConfigTestConstant.ARTIFACT_MAXSIZE));
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/DynamicConfigurationTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/DynamicConfigurationTest.java
new file mode 100644
index 0000000000..86422d2361
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/DynamicConfigurationTest.java
@@ -0,0 +1,66 @@
+package org.onap.config.test;
+
+import org.onap.config.api.Configuration;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.api.DynamicConfiguration;
+import org.onap.config.util.ConfigTestConstant;
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Properties;
+
+/**
+ * Created by sheetalm on 10/17/2016.
+ * Pre-requisite - set -Dconfig.location=${"user.home"}/TestResources/ while running test
+ * Scenario 20
+ * Update the central configuration and fetch the Dynamic Configuration
+ */
+public class DynamicConfigurationTest {
+
+ public final static String NAMESPACE = "DynamicConfiguration";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ TestUtil.writeFile(data);
+ }
+
+ @Test
+ public void testDynamicConfig() throws IOException, InterruptedException {
+ Configuration config = ConfigurationManager.lookup();
+ Properties props = new Properties();
+ props.setProperty(ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH, "20");
+ props.setProperty("_config.namespace",NAMESPACE);
+ props.setProperty("_config.mergeStrategy","override");
+ File f = new File(TestUtil.jsonSchemaLoc + "config.properties");
+ try (OutputStream out = new FileOutputStream(f)) {
+ props.store(out, "Override Config Property at Conventional Resource");
+ }
+
+ //Verify configuration with Configuration without wait. This should fetch cached value
+ Assert.assertEquals("14" , config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH));
+
+ Thread.sleep(10000);
+
+ DynamicConfiguration dynaConfig = config.getDynamicConfiguration(NAMESPACE,ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH,String.class,"14");
+ //Verify configuration with DynamicConfiguration This should fetch values from DB
+ Assert.assertEquals("20" , dynaConfig.get());
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ File f = new File(TestUtil.jsonSchemaLoc+"config.properties");
+ if(f.exists()) {
+ f.delete();
+ }
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/FallbackConfigTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/FallbackConfigTest.java
new file mode 100644
index 0000000000..17b4aee8b0
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/FallbackConfigTest.java
@@ -0,0 +1,38 @@
+package org.onap.config.test;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.onap.config.util.TestUtil.validateConfiguraton;
+import static org.onap.config.util.TestUtil.writeFile;
+
+/**
+ * Created by ARR on 10/14/2016.
+ *
+ * Validate configuration with properties,xml,json,yaml file format with mode
+ */
+public class FallbackConfigTest {
+
+ public static final String NAMESPACE = "fallback";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ writeFile(data);
+ }
+
+ @Test
+ public void testConfigurationWithFallbackFileFormat(){
+ validateConfiguraton(NAMESPACE);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ String data = "{name:\"SCM\"}";
+ writeFile(data);
+ //ConfigurationUtils.executeDDLSQL("truncate dox.configuration");
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/FallbackToGlobalNSTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/FallbackToGlobalNSTest.java
new file mode 100644
index 0000000000..14d74fb040
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/FallbackToGlobalNSTest.java
@@ -0,0 +1,42 @@
+package org.onap.config.test;
+
+import org.onap.config.api.Configuration;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.util.ConfigTestConstant;
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.Assert;
+
+import java.io.IOException;
+
+/**
+ * Scenario 12
+ * Verify configuration value fallback to the global namespace if the configuraton property doesnot exist in the namespace configuration
+ * Created by sheetalm on 10/14/2016.
+ */
+public class FallbackToGlobalNSTest {
+
+ public final static String NAMESPACE = "FallbackToGlobalNS";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ TestUtil.writeFile(data);
+ }
+
+ @Test
+ public void testFallbackToGlobalNS() throws IOException, InterruptedException {
+ Configuration config = ConfigurationManager.lookup();
+ Assert.assertEquals("14",config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH));
+ Assert.assertEquals("1024",config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_MAXSIZE));
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ }
+
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/GlobalAndNSConfigTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/GlobalAndNSConfigTest.java
new file mode 100644
index 0000000000..a0bb51a73f
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/GlobalAndNSConfigTest.java
@@ -0,0 +1,43 @@
+package org.onap.config.test;
+
+import org.onap.config.api.Configuration;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.util.ConfigTestConstant;
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+/**
+ * Created by sheetalm on 10/13/2016.
+ * Scenario 10 Verify configuration present in both global and defined namespace
+ */
+public class GlobalAndNSConfigTest {
+
+ public final static String NAMESPACE = "GlobalAndNSConfig";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ TestUtil.writeFile(data);
+ }
+
+ @Test
+ public void testNamespaceInConfig() throws IOException, InterruptedException {
+ Configuration config = ConfigurationManager.lookup();
+ Assert.assertEquals("a-zA-Z",config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_UPPER ));
+ Assert.assertEquals("a-zA-Z_0-9",config.getAsString(ConfigTestConstant.ARTIFACT_NAME_UPPER ));
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ }
+
+
+
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/JAVAPropertiesConfigTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/JAVAPropertiesConfigTest.java
new file mode 100644
index 0000000000..ab47765a1c
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/JAVAPropertiesConfigTest.java
@@ -0,0 +1,40 @@
+package org.onap.config.test;
+
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.onap.config.util.TestUtil.validateConfiguraton;
+import static org.onap.config.util.TestUtil.writeFile;
+
+/**
+ * Created by ARR on 10/13/2016.
+ *
+ * Scenario 1
+ * Validate configuration with Java Properties file format with mode
+ */
+public class JAVAPropertiesConfigTest {
+
+ public static final String NAMESPACE = "javaProperties";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ writeFile(data);
+ }
+
+ @Test
+ public void testConfigurationWithPropertiesFileFormat(){
+ validateConfiguraton(NAMESPACE);
+ }
+
+
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/JSONConfigTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/JSONConfigTest.java
new file mode 100644
index 0000000000..b3fcb730fb
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/JSONConfigTest.java
@@ -0,0 +1,40 @@
+package org.onap.config.test;
+
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.onap.config.util.TestUtil.validateConfiguraton;
+import static org.onap.config.util.TestUtil.writeFile;
+
+/**
+ * Created by ARR on 10/14/2016.
+ *
+ * Scenario 3
+ * Validate configuration with JSON file format with mode
+ */
+public class JSONConfigTest {
+
+ public static final String NAMESPACE = "JSONConfig";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ writeFile(data);
+ }
+
+ @Test
+ public void testConfigurationWithJSONFileFormat(){
+ validateConfiguraton(NAMESPACE);
+ }
+
+
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/LoadOrderMergeAndOverrideTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/LoadOrderMergeAndOverrideTest.java
new file mode 100644
index 0000000000..244511cbf0
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/LoadOrderMergeAndOverrideTest.java
@@ -0,0 +1,46 @@
+package org.onap.config.test;
+
+import static org.onap.config.util.TestUtil.writeFile;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.config.api.Configuration;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.util.ConfigTestConstant;
+import org.onap.config.util.TestUtil;
+
+import java.io.IOException;
+
+/**
+ * Scenario
+ * Check loadorder for merge and overide. Higher loadorder takes precedence for override
+ * LoWer loadorder takes precedence for merge.
+ */
+public class LoadOrderMergeAndOverrideTest {
+
+ public static final String NAMESPACE = "LoadOrderConfiguration";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ writeFile(data);
+ }
+
+ @Test
+ public void testConfigurationWithPropertiesFileFormat(){
+ Configuration config = ConfigurationManager.lookup();
+
+ Assert.assertEquals(config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH ), "14");
+ Assert.assertEquals("5", config.getAsString(NAMESPACE, "artifact.length"));
+ Assert.assertEquals("56", config.getAsString(NAMESPACE, "artifact.size"));
+ }
+
+
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ModeAsConfigPropTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ModeAsConfigPropTest.java
new file mode 100644
index 0000000000..17130d37c1
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ModeAsConfigPropTest.java
@@ -0,0 +1,87 @@
+package org.onap.config.test;
+
+import org.onap.config.api.Configuration;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.util.ConfigTestConstant;
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Scenario 8
+ * Validate configuration with mode specified as a configuration property
+ */
+
+public class ModeAsConfigPropTest {
+
+ String newValue = null;
+
+ public final static String NAMESPACE = "ModeAsConfigProp";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ TestUtil.writeFile(data);
+ }
+
+ @Test
+ public void testMergeStrategyInConfig() throws IOException, InterruptedException {
+ Configuration config = ConfigurationManager.lookup();
+
+ Assert.assertEquals("14",config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH));
+
+ Assert.assertEquals("1048",config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_MAXSIZE));
+
+ List<String> expectedExtList = new ArrayList<String>();
+ expectedExtList.add("pdf");
+ expectedExtList.add("zip");
+ expectedExtList.add("xml");
+ expectedExtList.add("pdf");
+ expectedExtList.add("tgz");
+ expectedExtList.add("xls");
+ List<String> extList = config.getAsStringValues(NAMESPACE, ConfigTestConstant.ARTIFACT_EXT);
+ Assert.assertEquals(expectedExtList, extList);
+
+ List<String> expectedEncList = new ArrayList<String>();
+ expectedEncList.add("Base64");
+ expectedEncList.add("MD5");
+ List<String> encList = config.getAsStringValues(NAMESPACE, ConfigTestConstant.ARTIFACT_ENC);
+ Assert.assertEquals(expectedEncList, encList);
+
+ String newValue = config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_JSON_SCHEMA);
+ Assert.assertEquals("{name:\"SCM\"}",config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_JSON_SCHEMA));
+
+ Assert.assertEquals("a-zA-Z_0-9",config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_UPPER ));
+
+ Assert.assertEquals("Deleted",config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_STATUS) );
+
+ List<String> expectedLocList = new ArrayList<String>();
+ expectedLocList.add("/opt/spool");
+ expectedLocList.add(System.getProperty("user.home")+"/asdc");
+ List<String> locList = config.getAsStringValues(NAMESPACE, ConfigTestConstant.ARTIFACT_LOC);
+ Assert.assertEquals(expectedLocList, locList);
+
+ Assert.assertEquals("@"+System.getenv("Path")+"/myschema.json",config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_XML_SCHEMA));
+
+ List<String> artifactConsumer = config.getAsStringValues(NAMESPACE, ConfigTestConstant.ARTIFACT_CONSUMER );
+ Assert.assertEquals(config.getAsStringValues(NAMESPACE, ConfigTestConstant.ARTIFACT_CONSUMER_APPC ), artifactConsumer);
+
+ Assert.assertEquals(config.getAsBooleanValue(NAMESPACE, ConfigTestConstant.ARTIFACT_MANDATORY_NAME ), true);
+
+ Assert.assertEquals(config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MINLENGTH ), "6");
+
+ Assert.assertEquals(config.getAsBooleanValue(NAMESPACE, ConfigTestConstant.ARTIFACT_ENCODED ), true);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ }
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/MultiTenancyConfigTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/MultiTenancyConfigTest.java
new file mode 100644
index 0000000000..8cdd634794
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/MultiTenancyConfigTest.java
@@ -0,0 +1,46 @@
+package org.onap.config.test;
+
+import org.onap.config.api.Configuration;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.util.ConfigTestConstant;
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+/**
+ * Created by ARR on 10/14/2016.
+ *
+ * Scenario 17
+ * Verify Configuration management System - Support for Multi-Tenancy
+ */
+public class MultiTenancyConfigTest {
+
+ public static final String NAMESPACE = "tenancy";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ TestUtil.writeFile(data);
+ }
+
+ @Test
+ public void testConfigurationWithMultiTenancyFileFormat(){
+ Configuration config = ConfigurationManager.lookup();
+
+ Assert.assertEquals(config.getAsString("OPENECOMP",NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH ), "20");
+
+ Assert.assertEquals(config.getAsString("Telefonica",NAMESPACE, ConfigTestConstant.ARTIFACT_STATUS ), "Deleted");
+
+ Assert.assertEquals(config.getAsString("TID",NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH ), "14");
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/NodeSpecificCLITest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/NodeSpecificCLITest.java
new file mode 100644
index 0000000000..59848f1dba
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/NodeSpecificCLITest.java
@@ -0,0 +1,117 @@
+package org.onap.config.test;
+
+import org.onap.config.util.ConfigTestConstant;
+import org.onap.config.Constants;
+import org.onap.config.api.ConfigurationChangeListener;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.util.TestUtil;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.management.JMX;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.lang.management.ManagementFactory;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Created by sheetalm on 10/19/2016.
+ * Scenario 19
+ * Pre-requisite - set -Dnode.config.location=${"user.home"}/TestResources/ while running test
+ * Verify node specific override using CLI
+ */
+public class NodeSpecificCLITest {
+
+ public final static String NAMESPACE = "NodeCLI";
+ private String updatedValue = "";
+
+ @Test
+ public void testCLIApi() throws Exception{
+ //Verify without fallback
+ Map<String, Object> input = new HashMap<>();
+ input.put("ImplClass", "org.openecomp.config.type.ConfigurationQuery");
+ input.put("namespace", NAMESPACE);
+ input.put("key", ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH);
+
+ MBeanServerConnection mbsc = ManagementFactory.getPlatformMBeanServer();
+ ObjectName mbeanName = new ObjectName(Constants.MBEAN_NAME);
+ ConfigurationManager conf = JMX.newMBeanProxy(mbsc, mbeanName, ConfigurationManager.class, true);
+ String maxLength = conf.getConfigurationValue(input);
+
+ //Verify Property from Namespace configurations
+ Assert.assertEquals("30",maxLength);
+
+ //Add node specific configurations
+ Properties props = new Properties();
+ props.setProperty(ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH, "50");
+ props.setProperty("_config.namespace",NAMESPACE);
+ File f = new File(TestUtil.jsonSchemaLoc + "config.properties");
+ try (OutputStream out = new FileOutputStream(f)) {
+ props.store(out, "Node Config Property");
+ }
+
+ Thread.sleep(35000);
+
+ //Verify property from node specific configuration
+ input.put("nodeSpecific", true);
+ String nodeVal = conf.getConfigurationValue(input);
+ Assert.assertEquals("50", nodeVal);
+
+ //Add Change Listener
+ conf.addConfigurationChangeListener(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH, new CLINodeListener());
+
+ //Update maxlength
+ input.put("ImplClass", "org.openecomp.config.type.ConfigurationUpdate");
+ input.put("nodeOverride", true);
+ input.put("nodeSpecific", false);
+ input.put("value", "60");
+ conf.updateConfigurationValue(input);
+
+ Thread.sleep(35000);
+
+ Assert.assertEquals("60",updatedValue);
+
+ //Fetch the updated nodespecific value
+ input.put("nodeOverride", false);
+ input.put("nodeSpecific", true);
+ input.put("ImplClass", "org.openecomp.config.type.ConfigurationQuery");
+ String updatedMaxLength = conf.getConfigurationValue(input);
+ Assert.assertEquals("60",updatedMaxLength);
+
+ //Verify maxlength on other nodes by deleting node specific configuration
+ if(f.exists()) {
+ f.delete();
+ }
+
+ Thread.sleep(35000);
+
+ input.put("ImplClass", "org.openecomp.config.type.ConfigurationQuery");
+ input.put("nodeOverride", false);
+ input.put("nodeSpecific", false);
+ System.out.println("val on other node is::"+conf.getConfigurationValue(input));
+ Assert.assertEquals("30",conf.getConfigurationValue(input));
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ File f = new File(TestUtil.jsonSchemaLoc+"config.properties");
+ if(f.exists()) {
+ f.delete();
+ }
+ }
+
+ private class CLINodeListener implements ConfigurationChangeListener {
+ @Override
+ public void notify(String key, Object oldValue, Object newValue) {
+ System.out.println("received notification::oldValue=="+oldValue+" newValue=="+newValue);
+ updatedValue = newValue.toString();
+ }
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/NotificationForNodeConfigTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/NotificationForNodeConfigTest.java
new file mode 100644
index 0000000000..55af6900a6
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/NotificationForNodeConfigTest.java
@@ -0,0 +1,85 @@
+package org.onap.config.test;
+
+import org.onap.config.api.Configuration;
+import org.onap.config.api.ConfigurationChangeListener;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.util.ConfigTestConstant;
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Properties;
+
+/**
+ * Scenario 15
+ * Update and Verify Change Notifications for any change in the registered key for node specific configuration
+ * Pre-requisite - set -Dnode.config.location=${"user.home"}/TestResources/ while running test
+ * Created by sheetalm on 10/17/2016.
+ */
+public class NotificationForNodeConfigTest {
+ public final static String NAMESPACE = "NotificationForNodeConfig";
+
+ private String updatedValue = null;
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ TestUtil.writeFile(data);
+ }
+
+ @Test
+ public void testNotificationForNode() throws IOException, InterruptedException {
+ Configuration config = ConfigurationManager.lookup();
+
+ System.out.println(config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH));
+
+ Properties props = new Properties();
+ props.setProperty(ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH, "30");
+ props.setProperty("_config.namespace",NAMESPACE);
+ File f = new File(TestUtil.jsonSchemaLoc + "config.properties");
+ try (OutputStream out = new FileOutputStream(f)) {
+ props.store(out, "Node Config Property");
+ }
+
+ Thread.sleep(35000);
+
+ //Verify property from node specific configuration
+ Assert.assertEquals("30", config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH));
+
+ config.addConfigurationChangeListener(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH, new NodePropValListener());
+
+ props.setProperty(ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH, "80");
+ try (OutputStream out = new FileOutputStream(f)) {
+ props.store(out, "Updated Node Config Property");
+ }
+
+ Thread.sleep(35000);
+
+ //Verify change listenere is invoked when node specific configuration is changed.
+ Assert.assertEquals("80", updatedValue);
+
+ }
+
+ private class NodePropValListener implements ConfigurationChangeListener {
+ @Override
+ public void notify(String key, Object oldValue, Object newValue) {
+ System.out.println("received notification::oldValue=="+oldValue+" newValue=="+newValue);
+ updatedValue = newValue.toString();
+ }
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ File f = new File(TestUtil.jsonSchemaLoc+"config.properties");
+ if(f.exists()) {
+ f.delete();
+ }
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/NotificationOnPropValTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/NotificationOnPropValTest.java
new file mode 100644
index 0000000000..c7b93b019a
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/NotificationOnPropValTest.java
@@ -0,0 +1,76 @@
+package org.onap.config.test;
+
+import org.onap.config.api.Configuration;
+import org.onap.config.api.ConfigurationChangeListener;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.util.ConfigTestConstant;
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.Assert;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Properties;
+
+/**
+ * Pre-requisite - set -Dconfig.location=${"user.home"}/TestResources/ while running test
+ * Scenario 14 - Verify Change Notifications for any change in the registered key
+ * Created by sheetalm on 10/14/2016.
+ */
+public class NotificationOnPropValTest {
+
+ public final static String NAMESPACE = "NotificationOnPropVal";
+
+ private String updatedValue = null;
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ TestUtil.writeFile(data);
+ }
+
+ @Test
+ public void testNotification() throws IOException, InterruptedException {
+ Configuration config = ConfigurationManager.lookup();
+
+ System.out.println(config.getAsString(NAMESPACE,ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH));
+
+ config.addConfigurationChangeListener(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH, new PropValListener());
+
+ Properties props = new Properties();
+ props.setProperty(ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH, "20");
+ props.setProperty("_config.namespace",NAMESPACE);
+ props.setProperty("_config.mergeStrategy","override");
+ File f = new File(TestUtil.jsonSchemaLoc + "config.properties");
+ try (OutputStream out = new FileOutputStream(f)) {
+ props.store(out, "Override Config Property at Conventional Resource");
+ }
+
+ Thread.sleep(35000);
+
+ System.out.println(config.getAsString(NAMESPACE,ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH));
+
+ Assert.assertEquals("20" , updatedValue);
+ }
+
+ private class PropValListener implements ConfigurationChangeListener {
+ @Override
+ public void notify(String key, Object oldValue, Object newValue) {
+ System.out.println("received notification::oldValue=="+oldValue+" newValue=="+newValue);
+ updatedValue = newValue.toString();
+ }
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ File f = new File(TestUtil.jsonSchemaLoc+"config.properties");
+ if(f.exists()) {
+ f.delete();
+ }
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ResourceChangeNotificationTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ResourceChangeNotificationTest.java
new file mode 100644
index 0000000000..54bd339f29
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ResourceChangeNotificationTest.java
@@ -0,0 +1,88 @@
+package org.onap.config.test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.onap.config.util.ConfigTestConstant;
+
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.onap.config.api.Configuration;
+import org.onap.config.api.ConfigurationChangeListener;
+import org.onap.config.api.ConfigurationManager;
+
+/**
+ * Scenario 7
+ * Test to Validate notification on changes to the underlying source
+ * Resource here is GeneratorsList.json ehich is created in test itself
+ */
+
+public class ResourceChangeNotificationTest {
+
+ String newValue = null;
+
+ public final static String NAMESPACE = "Notification";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ TestUtil.writeFile(data);
+ }
+
+ @Test
+ public void testNotification() throws IOException, InterruptedException {
+ Configuration config = ConfigurationManager.lookup();
+ config.addConfigurationChangeListener(NAMESPACE,ConfigTestConstant.ARTIFACT_JSON_SCHEMA, new MyListener());
+ updateJsonInFile();
+ Thread.sleep(35000);
+ String newValue = config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_JSON_SCHEMA);
+
+ Assert.assertEquals("{name:\"updated SCM\"}",newValue);
+
+ Assert.assertEquals( "14",config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH ));
+
+ Assert.assertEquals( "a-zA-Z", config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_UPPER ));
+
+ String artifactConsumer = config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_CONSUMER );
+ Assert.assertEquals(artifactConsumer,config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_CONSUMER_APPC ));
+
+ List<String> expectedExtList = new ArrayList<String>();
+ expectedExtList.add("pdf"); expectedExtList.add("zip"); expectedExtList.add("xml");
+ List<String> extList = config.getAsStringValues(NAMESPACE, ConfigTestConstant.ARTIFACT_EXT);
+ Assert.assertEquals(expectedExtList, extList);
+
+ List<String> expectedEncList = new ArrayList<String>();
+ expectedEncList.add("Base64"); expectedEncList.add("MD5");
+ List<String> encList = config.getAsStringValues(NAMESPACE, ConfigTestConstant.ARTIFACT_ENC);
+ Assert.assertEquals(expectedEncList, encList);
+
+ List<String> expectedLocList = new ArrayList<String>();
+ expectedLocList.add("/opt/spool"); expectedLocList.add(System.getProperty("user.home")+"/asdc");
+ List<String> locList = config.getAsStringValues(NAMESPACE, ConfigTestConstant.ARTIFACT_LOC);
+ Assert.assertEquals(expectedLocList, locList);
+
+ Assert.assertEquals("@"+System.getenv("Path")+"/myschema.json",config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_XML_SCHEMA));
+ }
+
+ class MyListener implements ConfigurationChangeListener{
+ @Override
+ public void notify(String key, Object oldValue, Object newValue) {
+ System.out.println("received notification::oldValue=="+oldValue+" newValue=="+newValue);
+ }
+ }
+
+ private void updateJsonInFile() throws IOException{
+ String data = "{name:\"updated SCM\"}";
+ TestUtil.writeFile(data);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/UnregisterNotificationTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/UnregisterNotificationTest.java
new file mode 100644
index 0000000000..cdfcfdf22d
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/UnregisterNotificationTest.java
@@ -0,0 +1,94 @@
+package org.onap.config.test;
+
+import org.onap.config.api.Configuration;
+import org.onap.config.api.ConfigurationChangeListener;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.util.ConfigTestConstant;
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Properties;
+
+/**
+ * Pre-requisite - set -Dconfig.location=${"user.home"}/TestResources/ while running test
+ * Created by sheetalm on 10/19/2016.
+ * Scenario 24
+ * Unregister notification and verify listener
+ */
+public class UnregisterNotificationTest {
+ public final static String NAMESPACE = "UnregisterNotification";
+
+ private String updatedValue = null;
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ TestUtil.writeFile(data);
+ }
+
+ @Test
+ public void testNotification() throws IOException, InterruptedException {
+ Configuration config = ConfigurationManager.lookup();
+
+ System.out.println(config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH));
+
+ PropertyListener propListener = new PropertyListener();
+ config.addConfigurationChangeListener(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH,propListener);
+
+ updateValue("20");
+
+ Thread.sleep(35000);
+
+ System.out.println(config.getAsString(NAMESPACE,ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH));
+
+ //Verify listener is invoked and updated value to 20
+ Assert.assertEquals("20" , updatedValue);
+
+ config.removeConfigurationChangeListener(NAMESPACE,ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH,propListener);
+
+ updateValue("22");
+
+ Thread.sleep(35000);
+
+ //When listener is unregistered updating value does not invoke any listener and value from listener should remain unchanged
+ Assert.assertEquals("20" , updatedValue);
+
+ //Verify value is updated even if listener is unregistered
+ Assert.assertEquals("22" , config.getAsString(NAMESPACE,ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH));
+ }
+
+ private void updateValue(String newValue) throws IOException {
+ Properties props = new Properties();
+ props.setProperty(ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH, newValue);
+ props.setProperty("_config.namespace",NAMESPACE);
+ props.setProperty("_config.mergeStrategy","override");
+ File f = new File(TestUtil.jsonSchemaLoc+"config.properties");
+ try (OutputStream out = new FileOutputStream(f)) {
+ props.store(out, "Override Config Property at Conventional Resource");
+ }
+ }
+
+ private class PropertyListener implements ConfigurationChangeListener {
+ @Override
+ public void notify(String key, Object oldValue, Object newValue) {
+ System.out.println("received notification::oldValue=="+oldValue+" newValue=="+newValue);
+ updatedValue = newValue.toString();
+ }
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ File f = new File(TestUtil.jsonSchemaLoc+"config.properties");
+ if(f.exists()) {
+ f.delete();
+ }
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ValidateDefaultModeTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ValidateDefaultModeTest.java
new file mode 100644
index 0000000000..f9ce9a37ed
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ValidateDefaultModeTest.java
@@ -0,0 +1,58 @@
+package org.onap.config.test;
+
+import org.onap.config.api.Configuration;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.util.ConfigTestConstant;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.onap.config.util.TestUtil.writeFile;
+
+/**
+ * Created by ARR on 10/17/2016.
+ *
+ * Scenario 22
+ * Validate the default mode if the mode is not set
+ */
+public class ValidateDefaultModeTest {
+
+ public static final String NAMESPACE = "defaultmode";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ writeFile(data);
+ }
+
+ @Test
+ public void testConfigurationWithValidateDefaultMode(){
+ Configuration config = ConfigurationManager.lookup();
+
+ Assert.assertEquals(config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH ), "14");
+
+ Assert.assertEquals(config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_MAXSIZE ), "1048");
+
+ List<String> expectedExtList = new ArrayList<String>();
+ expectedExtList.add("pdf");
+ expectedExtList.add("tgz");
+ expectedExtList.add("xls");
+ List<String> extList = config.getAsStringValues(NAMESPACE, ConfigTestConstant.ARTIFACT_EXT);
+ Assert.assertEquals(expectedExtList, extList);
+
+ Assert.assertEquals(config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MINLENGTH ), "6");
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ String data = "{name:\"SCM\"}";
+ writeFile(data);
+ // ConfigurationUtils.executeDDLSQL("truncate dox.configuration");
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ValidateNodeConfigTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ValidateNodeConfigTest.java
new file mode 100644
index 0000000000..e4f3a84b05
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/ValidateNodeConfigTest.java
@@ -0,0 +1,80 @@
+package org.onap.config.test;
+
+import org.onap.config.api.Configuration;
+import org.onap.config.api.ConfigurationManager;
+import org.onap.config.util.ConfigTestConstant;
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.Assert;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Properties;
+
+/**
+ * Scenario 13
+ * Validate node specific configuration
+ * Pre-requisite - set -Dnode.config.location=${"user.home"}/TestResources/ while running test
+ *
+ * Created by sheetalm on 10/14/2016.
+ */
+public class ValidateNodeConfigTest {
+
+ public final static String NAMESPACE = "ValidateNodeConfig";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ TestUtil.writeFile(data);
+ }
+
+ @Test
+ public void testValidateNodeConfig() throws IOException, InterruptedException {
+ Configuration config = ConfigurationManager.lookup();
+
+ Properties props = new Properties();
+ props.setProperty(ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH, "56");
+ props.setProperty("_config.namespace","ValidateNodeConfig");
+ File f = new File(TestUtil.jsonSchemaLoc+"config.properties");
+ try (OutputStream out = new FileOutputStream(f)) {
+ props.store(out, "Node Config Property");
+ }
+
+ System.out.println(System.getProperty("node.config.location"));
+
+ Thread.sleep(35000);
+
+ //Verify property from node specific configuration
+ Assert.assertEquals("56", config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH));
+
+ //Verify if property is not in node specific then fetch from namespace
+ //Assert.assertEquals("a-zA-Z",config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_UPPER));
+
+ //Verify if property is not in node specific and namespace then fetch from global
+ Assert.assertEquals("1024", config.getAsString(NAMESPACE, "maxCachedBufferSize"));
+
+ //Deleting node configurations to test property is fetched from namespace configuration when node configuration is not present
+ if(f.exists()) {
+ boolean isDeleted = f.delete();
+ System.out.println(isDeleted);
+ }
+
+ Thread.sleep(35000);
+
+ Assert.assertEquals(config.getAsString(NAMESPACE, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH), "14");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ File f = new File(TestUtil.jsonSchemaLoc+"config.properties");
+ if(f.exists()) {
+ f.delete();
+ }
+ }
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/XMLConfigTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/XMLConfigTest.java
new file mode 100644
index 0000000000..ae6fc3e7b1
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/XMLConfigTest.java
@@ -0,0 +1,40 @@
+package org.onap.config.test;
+
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.onap.config.util.TestUtil.validateConfiguraton;
+import static org.onap.config.util.TestUtil.writeFile;
+
+/**
+ * Created by ARR on 10/14/2016.
+ *
+ * Scenario 2
+ * Validate configuration with XML file format with mode
+ */
+public class XMLConfigTest {
+
+ public static final String NAMESPACE = "XMLConfig";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ writeFile(data);
+ }
+
+ @Test
+ public void testConfigurationWithXMLFileFormat(){
+ validateConfiguraton(NAMESPACE);
+ }
+
+
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/YAMLConfigTest.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/YAMLConfigTest.java
new file mode 100644
index 0000000000..46240402f4
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/test/YAMLConfigTest.java
@@ -0,0 +1,40 @@
+package org.onap.config.test;
+
+import org.onap.config.util.TestUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.onap.config.util.TestUtil.validateConfiguraton;
+import static org.onap.config.util.TestUtil.writeFile;
+
+/**
+ * Created by ARR on 10/14/2016.
+ *
+ * Scenario 4
+ * Validate configuration with YAML file format with mode
+ */
+public class YAMLConfigTest {
+
+ public static final String NAMESPACE = "YAMLConfig";
+
+ @Before
+ public void setUp() throws IOException {
+ String data = "{name:\"SCM\"}";
+ writeFile(data);
+ }
+
+ @Test
+ public void testConfigurationWithYAMLFileFormat(){
+ validateConfiguraton(NAMESPACE);
+ }
+
+
+
+ @After
+ public void tearDown() throws Exception {
+ TestUtil.cleanUp();
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/util/ConfigTestConstant.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/util/ConfigTestConstant.java
new file mode 100644
index 0000000000..1d4dead7d2
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/util/ConfigTestConstant.java
@@ -0,0 +1,23 @@
+package org.onap.config.util;
+
+public class ConfigTestConstant {
+
+ public static final String ARTIFACT_NAME_MAXLENGTH = "artifact.name.maxlength";
+ public static final String ARTIFACT_MAXSIZE = "artifact.maxsize";
+ public static final String ARTIFACT_EXT = "artifact.extension";
+ public static final String ARTIFACT_ENC = "artifact.supportedEncryption";
+ public static final String ARTIFACT_NAME_UPPER = "artifact.name.allowedChar";
+ public static final String ARTIFACT_NAME_LOWER = "artifact.name.allowedchar";
+ public static final String ARTIFACT_STATUS = "artifact.status";
+ public static final String ARTIFACT_LOC = "artifact.persistLocation";
+ public static final String ARTIFACT_JSON_SCHEMA = "artifact.jsonSchema";
+ public static final String ARTIFACT_XML_SCHEMA = "artifact.xmlSchema";
+ public static final String ARTIFACT_CONSUMER_APPC = "artifact.consumerAPPC";
+ public static final String ARTIFACT_CONSUMER = "artifact.consumer";
+ public static final String ARTIFACT_MANDATORY_NAME = "artifact.mandatory.name";
+ public static final String ARTIFACT_NAME_MINLENGTH = "artifact.name.minlength";
+ public static final String ARTIFACT_ENCODED = "artifact.encoded";
+
+ public static final String ONBOARDING_NAMESPACE = "onboarding";
+
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/util/TestUtil.java b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/util/TestUtil.java
new file mode 100644
index 0000000000..83f0371c33
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/java/org/onap/config/util/TestUtil.java
@@ -0,0 +1,91 @@
+package org.onap.config.util;
+
+import org.onap.config.ConfigurationUtils;
+import org.onap.config.api.Configuration;
+import org.onap.config.api.ConfigurationManager;
+import org.junit.Assert;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by sheetalm on 10/13/2016.
+ */
+public class TestUtil {
+
+ public final static String jsonSchemaLoc = System.getProperty("user.home")+"/TestResources/";
+ public static FileWriter fileWriter ;
+
+ public static void writeFile(String data) throws IOException {
+ File dir = new File(jsonSchemaLoc);
+ File file = null;
+ dir.mkdirs();
+ file = new File(jsonSchemaLoc+"/GeneratorsList.json");
+ file.createNewFile();
+ fileWriter = new FileWriter(file);
+ fileWriter.write(data);
+ fileWriter.close();
+ }
+
+ public static void cleanUp() throws Exception {
+ String data = "{name:\"SCM\"}";
+ TestUtil.writeFile(data);
+ //ConfigurationUtils.executeDdlSql("truncate dox.configuration");
+ try{
+ ConfigurationUtils.executeDdlSql("truncate dox.configuration_change");
+ }
+ catch(Exception e){
+ e.printStackTrace();
+ }
+
+ }
+
+ public static void validateConfiguraton(String nameSpace) {
+ Configuration config = ConfigurationManager.lookup();
+
+ Assert.assertEquals(config.getAsString(nameSpace, ConfigTestConstant.ARTIFACT_NAME_MAXLENGTH ), "14");
+
+ // First value from list is picked from Merge properties
+ Assert.assertEquals(config.getAsString(nameSpace, ConfigTestConstant.ARTIFACT_MAXSIZE ), "1048576");
+
+ List<String> expectedExtList = new ArrayList<String>();
+ expectedExtList.add("pdf");
+ expectedExtList.add("zip");
+ expectedExtList.add("xml");
+ expectedExtList.add("pdf");
+ expectedExtList.add("tgz");
+ expectedExtList.add("xls");
+ List<String> extList = config.getAsStringValues(nameSpace, ConfigTestConstant.ARTIFACT_EXT);
+ Assert.assertEquals(expectedExtList, extList);
+
+ List<String> expectedEncList = new ArrayList<String>();
+ expectedEncList.add("Base64");
+ expectedEncList.add("MD5");
+ List<String> encList = config.getAsStringValues(nameSpace, ConfigTestConstant.ARTIFACT_ENC);
+ Assert.assertEquals(expectedEncList, encList);
+
+ Assert.assertEquals(config.getAsString(nameSpace, ConfigTestConstant.ARTIFACT_NAME_UPPER ), "a-zA-Z_0-9");
+ Assert.assertEquals(config.getAsString(nameSpace, ConfigTestConstant.ARTIFACT_NAME_LOWER ), "a-zA-Z");
+ Assert.assertEquals(config.getAsString(nameSpace, ConfigTestConstant.ARTIFACT_STATUS ), "deleted");
+
+ List<String> expectedLocList = new ArrayList<String>();
+ expectedLocList.add("/opt/spool");
+ expectedLocList.add(System.getProperty("user.home")+"/asdc");
+ List<String> locList = config.getAsStringValues(nameSpace, ConfigTestConstant.ARTIFACT_LOC);
+ Assert.assertEquals(expectedLocList, locList);
+
+ Assert.assertEquals(config.getAsString(nameSpace, ConfigTestConstant.ARTIFACT_JSON_SCHEMA ), "@GeneratorList.json");
+
+ Assert.assertEquals("@"+System.getenv("Path")+"/myschema.json",config.getAsString(nameSpace, ConfigTestConstant.ARTIFACT_XML_SCHEMA));
+
+ List<String> artifactConsumer = config.getAsStringValues(nameSpace, ConfigTestConstant.ARTIFACT_CONSUMER );
+ Assert.assertEquals(config.getAsStringValues(nameSpace, ConfigTestConstant.ARTIFACT_CONSUMER_APPC ), artifactConsumer);
+
+ Assert.assertEquals(config.getAsString(nameSpace, ConfigTestConstant.ARTIFACT_NAME_MINLENGTH ), "6");
+ Assert.assertEquals(config.getAsString(nameSpace, ConfigTestConstant.ARTIFACT_MANDATORY_NAME ), "true");
+ Assert.assertEquals(config.getAsString(nameSpace, ConfigTestConstant.ARTIFACT_ENCODED ), "true");
+ }
+}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config-NS.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config-NS.properties
new file mode 100644
index 0000000000..a50cabc151
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config-NS.properties
@@ -0,0 +1,12 @@
+artifact.name.maxlength=14
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.supportedEncryption=MD5
+artifact.name.allowedChar=a-zA-Z
+artifact.status=deleted
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@${sys:user.home}/TestResources/GeneratorsList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=OPENECOMP:CLI \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.json
new file mode 100644
index 0000000000..5d98a327db
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.json
@@ -0,0 +1,8 @@
+{
+ "artifact": {
+ "name": { "minlength": "6" },
+ "extension": "pdf,tgz,xls"
+ },
+ "_config":{"namespace": "OPENECOMP:CLI", "mergeStrategy": "union"}
+
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.properties
new file mode 100644
index 0000000000..4daad19dcc
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.properties
@@ -0,0 +1,3 @@
+maxCachedBufferSize=1024
+artifact.maxsize=1024
+artifact.name.maxlength=28 \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.xml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.xml
new file mode 100644
index 0000000000..2f09871bd5
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <artifact>
+ <name>
+ <maxlength>28</maxlength>
+ </name>
+ <extension>gz,tgz</extension>
+ <supportedencryption>Base64</supportedencryption>
+ <status>deleted</status>
+ <mandatory>
+ <name>true</name>
+ </mandatory>
+ <_config>
+ <namespace>OPENECOMP:CLI</namespace>
+ <mergeStrategy>merge</mergeStrategy>
+ </_config>
+ </artifact>
+</configuration> \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.yaml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.yaml
new file mode 100644
index 0000000000..4333f3e83e
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLI/config.yaml
@@ -0,0 +1,8 @@
+artifact:
+ name:
+ allowedChar: "a-zA-Z_0-9"
+ encoded: true
+ consumer: "appc,catalog"
+_config:
+ namespace: "OPENECOMP:CLI"
+ mergeStrategy: "override" \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config-NS.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config-NS.properties
new file mode 100644
index 0000000000..32da54ffbc
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config-NS.properties
@@ -0,0 +1,12 @@
+artifact.name.maxlength=14
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.supportedEncryption=MD5
+artifact.name.allowedChar=a-zA-Z
+artifact.status=deleted
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@${sys:user.home}/TestResources/GeneratorsList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=OPENECOMP:CLIFallback \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.json
new file mode 100644
index 0000000000..a1db251671
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.json
@@ -0,0 +1,8 @@
+{
+ "artifact": {
+ "name": { "minlength": "6" },
+ "extension": "pdf,tgz,xls"
+ },
+ "_config":{"namespace": "OPENECOMP:CLIFallback", "mergeStrategy": "union"}
+
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.properties
new file mode 100644
index 0000000000..4daad19dcc
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.properties
@@ -0,0 +1,3 @@
+maxCachedBufferSize=1024
+artifact.maxsize=1024
+artifact.name.maxlength=28 \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.xml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.xml
new file mode 100644
index 0000000000..4c46762cdd
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <artifact>
+ <name>
+ <maxlength>28</maxlength>
+ </name>
+ <extension>gz,tgz</extension>
+ <supportedencryption>Base64</supportedencryption>
+ <status>deleted</status>
+ <mandatory>
+ <name>true</name>
+ </mandatory>
+ <_config>
+ <namespace>OPENECOMP:CLIFallback</namespace>
+ <mergeStrategy>merge</mergeStrategy>
+ </_config>
+ </artifact>
+</configuration> \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.yaml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.yaml
new file mode 100644
index 0000000000..b0b195f354
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/CLIFallback/config.yaml
@@ -0,0 +1,8 @@
+artifact:
+ name:
+ allowedChar: "a-zA-Z_0-9"
+ encoded: true
+ consumer: "appc,catalog"
+_config:
+ namespace: "OPENECOMP:CLIFallback"
+ mergeStrategy: "override" \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.json
new file mode 100644
index 0000000000..c909fe8466
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.json
@@ -0,0 +1,8 @@
+{
+
+ "artifact": {
+ "name": { "minlength": "6" },
+ "extension": "pdf,tgz,xls"
+ },
+ "_config": {"namespace": "DynamicConfiguration", "mergeStrategy": "union"}
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.properties
new file mode 100644
index 0000000000..c3825487a9
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.properties
@@ -0,0 +1,13 @@
+artifact.name.maxlength=14
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.supportedEncryption=MD5
+artifact.name.allowedChar=a-zA-Z
+artifact.name.allowedchar=a-zA-Z
+artifact.status=deleted
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorsList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=DynamicConfiguration \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.xml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.xml
new file mode 100644
index 0000000000..3f046e232b
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <artifact>
+ <name>
+ <maxlength>28</maxlength>
+ </name>
+ <extension>gz,tgz</extension>
+ <supportedencryption>Base64</supportedencryption>
+ <status>deleted</status>
+ <mandatory>
+ <name>true</name>
+ </mandatory>
+ <_config>
+ <namespace>DynamicConfiguration</namespace>
+ <mergeStrategy>merge</mergeStrategy>
+ </_config>
+ </artifact>
+</configuration> \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.yaml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.yaml
new file mode 100644
index 0000000000..12ba1f093e
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/DynamicConfiguration/config.yaml
@@ -0,0 +1,8 @@
+artifact:
+ name:
+ allowedChar: "a-zA-Z_0-9"
+encoded: true
+consumer: "appc,catalog"
+_config:
+ namespace: "DynamicConfiguration"
+ mergeStrategy: "override"
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config-NS.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config-NS.properties
new file mode 100644
index 0000000000..b7e985b90a
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config-NS.properties
@@ -0,0 +1,13 @@
+artifact.name.maxlength=14
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.supportedEncryption=MD5
+artifact.name.allowedChar=a-zA-Z
+artifact.name.allowedchar=a-zA-Z
+artifact.status=deleted
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorsList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=FallbackToGlobalNS \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.json
new file mode 100644
index 0000000000..6f3d68ab75
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.json
@@ -0,0 +1,9 @@
+{
+
+ "artifact": {
+ "name": { "minlength": "6" },
+ "extension": "pdf,tgz,xls"
+ },
+ "_config":{"namespace": "FallbackToGlobalNS" , "mergeStrategy": "union"}
+
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.properties
new file mode 100644
index 0000000000..4daad19dcc
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.properties
@@ -0,0 +1,3 @@
+maxCachedBufferSize=1024
+artifact.maxsize=1024
+artifact.name.maxlength=28 \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.xml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.xml
new file mode 100644
index 0000000000..9a881ab4a7
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <artifact>
+ <name>
+ <maxlength>28</maxlength>
+ </name>
+ <extension>gz,tgz</extension>
+ <supportedencryption>Base64</supportedencryption>
+ <status>deleted</status>
+ <mandatory>
+ <name>true</name>
+ </mandatory>
+ </artifact>
+ <_config>
+ <namespace>FallbackToGlobalNS</namespace>
+ <mergeStrategy>merge</mergeStrategy>
+ </_config>
+
+</configuration> \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.yaml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.yaml
new file mode 100644
index 0000000000..46f50b6087
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/FallbackToGlobalNS/config.yaml
@@ -0,0 +1,8 @@
+artifact:
+ name:
+ allowedChar: "a-zA-Z_0-9"
+ encoded: true
+ consumer: "appc,catalog"
+ _config:
+ namespace: "FallbackToGlobalNS"
+ mergeStrategy: "override"
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.json
new file mode 100644
index 0000000000..e59e65855c
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.json
@@ -0,0 +1,10 @@
+{
+
+ "artifact": {
+ "name": { "minlength": "6" },
+ "maxsize": "1048",
+ "extension": "pdf,tgz,xls"
+ },
+ "_config": { "mergeStrategy": "union","namespace":"GlobalAndNSConfig" }
+
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.properties
new file mode 100644
index 0000000000..1a86f68a65
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.properties
@@ -0,0 +1,10 @@
+artifact.name.maxlength=14
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64, MD5
+artifact.name.allowedChar=a-zA-Z
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorsList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=GlobalAndNSConfig \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.xml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.xml
new file mode 100644
index 0000000000..d8292c167e
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <artifact>
+ <name>
+ <maxlength>28</maxlength>
+ </name>
+ <extension>gz,tgz</extension>
+ <mandatory>
+ <name>true</name>
+ </mandatory>
+ </artifact>
+ <_config>
+ <namespace>GlobalAndNSConfig</namespace>
+ <mergeStrategy>merge</mergeStrategy>
+ </_config>
+</configuration> \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.yaml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.yaml
new file mode 100644
index 0000000000..bbbdde22a4
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/GlobalAndNSConfig/config.yaml
@@ -0,0 +1,7 @@
+ artifact:
+ name:
+ allowedChar: "a-zA-Z_0-9"
+ encoded: true
+ consumer: "appc,catalog"
+ _config:
+ mergeStrategy: "override" \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config-M.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config-M.json
new file mode 100644
index 0000000000..9c335724bc
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config-M.json
@@ -0,0 +1,16 @@
+{
+
+ "artifact": {
+ "name": { "maxlength": "28" },
+ "maxsize": "1048576",
+ "extension": "gz,tgz",
+ "supportedencryption": "Base64",
+ "status": "deleted",
+ "mandatory": { "name": "true" }
+ },
+ "_config": {
+ "namespace": "JSONConfig",
+ "mergeStrategy": "merge"
+ }
+
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config-O.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config-O.json
new file mode 100644
index 0000000000..c324fc777c
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config-O.json
@@ -0,0 +1,11 @@
+{
+ "artifact": {
+ "name": { "allowedChar": "a-zA-Z_0-9" },
+ "encoded": "true",
+ "consumer": "appc,catalog"
+ },
+ "_config": {
+ "namespace": "JSONConfig",
+ "mergeStrategy": "override"
+ }
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config-U.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config-U.json
new file mode 100644
index 0000000000..05a7e2d7ff
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config-U.json
@@ -0,0 +1,11 @@
+{
+ "artifact": {
+ "name": { "minlength": "6" },
+ "maxsize": "1048",
+ "extension": "pdf,tgz,xls"
+ },
+ "_config": {
+ "namespace": "JSONConfig",
+ "mergeStrategy": "union"
+ }
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config.json
new file mode 100644
index 0000000000..0538ba1717
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/JSONConfiguration/config.json
@@ -0,0 +1,30 @@
+{
+ "artifact": {
+ "name": {
+ "maxlength": "14",
+ "allowedChar": "a-zA-Z",
+ "allowedchar": "a-zA-Z"
+ },
+ "extension": [
+ "pdf",
+ "zip,xml"
+
+ ],
+ "supportedEncryption": [
+ "Base64",
+ "MD5"
+ ],
+ "status": [
+ "deleted",
+ "Deleted"
+ ],
+ "persistLocation": "/opt/spool,${sys:user.home}/asdc",
+ "jsonSchema": "@GeneratorList.json",
+ "xmlSchema": "@${env:path}/myschema.json",
+ "consumerAPPC": "${artifact.consumer}"
+
+ },
+ "_config": {
+ "namespace": "JSONConfig"
+ }
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-M.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-M.properties
new file mode 100644
index 0000000000..5082081102
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-M.properties
@@ -0,0 +1,9 @@
+artifact.name.maxlength=28
+artifact.maxsize=1048576
+artifact.extension=gz, tgz
+artifact.supportedencryption=Base64
+artifact.mandatory.name=true
+artifact.length=2
+_config.namespace=LoadOrderConfiguration
+_config.mergeStrategy=merge
+_config.loadOrder=2 \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-O.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-O.properties
new file mode 100644
index 0000000000..45018269dd
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-O.properties
@@ -0,0 +1,7 @@
+artifact.name.allowedChar=a-zA-Z_0-9
+artifact.encoded=true
+artifact.consumer=appc, catalog
+artifact.size=75
+_config.namespace=LoadOrderConfiguration
+_config.mergeStrategy=override
+_config.loadOrder=1 \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-U.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-U.properties
new file mode 100644
index 0000000000..cb5d5968f5
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-U.properties
@@ -0,0 +1,5 @@
+artifact.maxsize=1048
+artifact.extension=pdf,tgz, xls
+artifact.name.minlength=6
+_config.namespace=LoadOrderConfiguration
+_config.mergeStrategy=union \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-loadorder-M.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-loadorder-M.properties
new file mode 100644
index 0000000000..79d0815a39
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-loadorder-M.properties
@@ -0,0 +1,9 @@
+artifact.name.maxlength=28
+artifact.maxsize=1048576
+artifact.extension=gz, tgz
+artifact.supportedencryption=Base64
+artifact.mandatory.name=true
+artifact.length=5
+_config.namespace=LoadOrderConfiguration
+_config.mergeStrategy=merge
+_config.loadOrder=1 \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-loadorder-O.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-loadorder-O.properties
new file mode 100644
index 0000000000..164706dba7
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config-loadorder-O.properties
@@ -0,0 +1,7 @@
+artifact.name.allowedChar=a-zA-Z_0-9
+artifact.encoded=true
+artifact.consumer=appc, catalog
+artifact.size=56
+_config.namespace=LoadOrderConfiguration
+_config.mergeStrategy=override
+_config.loadOrder=2 \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config.properties
new file mode 100644
index 0000000000..ae1f445efd
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/LoadOrderConfiguration/config.properties
@@ -0,0 +1,14 @@
+artifact.name.maxlength=14
+#artifact.maxsize=
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.supportedEncryption=MD5
+artifact.name.allowedChar=a-zA-Z
+artifact.name.allowedchar=a-zA-Z
+artifact.status=deleted
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=LoadOrderConfiguration
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.json
new file mode 100644
index 0000000000..7c6d552b82
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.json
@@ -0,0 +1,8 @@
+{
+ "artifact": {
+ "name": { "minlength": "6" },
+ "maxsize": "1048",
+ "extension": "pdf,tgz,xls"
+ },
+ "_config": { "mergeStrategy": "union" , "namespace":"ModeAsConfigProp" }
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.properties
new file mode 100644
index 0000000000..a82e6b23fe
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.properties
@@ -0,0 +1,10 @@
+artifact.name.maxlength=14
+artifact.extension=pdf,zip,xml
+artifact.supportedEncryption=Base64,MD5
+artifact.name.allowedChar=a-zA-Z
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@${sys:user.home}/TestResources/GeneratorsList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=ModeAsConfigProp \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.xml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.xml
new file mode 100644
index 0000000000..2d05d2724c
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <artifact>
+ <name>
+ <maxlength>28</maxlength>
+ </name>
+ <extension>gz,tgz</extension>
+ <mandatory>
+ <name>true</name>
+ </mandatory>
+ </artifact>
+ <_config>
+ <namespace>ModeAsConfigProp</namespace>
+ <mergeStrategy>merge</mergeStrategy>
+ </_config>
+</configuration> \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.yaml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.yaml
new file mode 100644
index 0000000000..ef08bba6ce
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/MergeStrategyAsConfigProp/config.yaml
@@ -0,0 +1,8 @@
+artifact:
+ name:
+ allowedChar: "a-zA-Z_0-9"
+ encoded: true
+ consumer: "appc,catalog"
+_config:
+ mergeStrategy: "override"
+ namespace: "ModeAsConfigProp" \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NodeCLI/config.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NodeCLI/config.properties
new file mode 100644
index 0000000000..435f98ab39
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NodeCLI/config.properties
@@ -0,0 +1,9 @@
+artifact.name.maxlength=30
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.name.allowedChar=a-zA-Z
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorsList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=NodeCLI \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/Notification/config.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/Notification/config.properties
new file mode 100644
index 0000000000..4076eefa58
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/Notification/config.properties
@@ -0,0 +1,15 @@
+artifact.name.maxlength=14
+artifact.consumer=APPC
+artifact.maxsize=1048
+artifact.extension=pdf,zip,xml
+artifact.supportedEncryption=Base64
+artifact.supportedEncryption=MD5
+artifact.name.allowedChar=a-zA-Z
+artifact.name.allowedchar=a-zA-Z
+artifact.status=deleted
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool,${sys:user.home}/asdc
+artifact.jsonSchema=@${sys:user.home}/TestResources/GeneratorsList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=Notification \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig.zip b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig.zip
new file mode 100644
index 0000000000..42d14a64db
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig.zip
Binary files differ
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.json
new file mode 100644
index 0000000000..0d6395af4f
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.json
@@ -0,0 +1,12 @@
+{
+
+ "artifact": {
+ "name": { "minlength": "6" },
+ "extension": "pdf,tgz,xls"
+ },
+ "_config":{
+ "namespace": "NotificationForNodeConfig",
+ "mergestrategy": "union"
+ }
+
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.properties
new file mode 100644
index 0000000000..d2c41aa4b5
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.properties
@@ -0,0 +1,14 @@
+artifact.name.maxlength=14
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.supportedEncryption=MD5
+artifact.name.allowedChar=a-zA-Z
+artifact.name.allowedchar=a-zA-Z
+artifact.status=deleted
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorsList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=NotificationForNodeConfig
+
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.xml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.xml
new file mode 100644
index 0000000000..20768aa949
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <artifact>
+ <name>
+ <maxlength>28</maxlength>
+ </name>
+ <extension>gz,tgz</extension>
+ <supportedencryption>Base64</supportedencryption>
+ <status>deleted</status>
+ <mandatory>
+ <name>true</name>
+ </mandatory>
+ </artifact>
+ <_config>
+ <namespace>NotificationForNodeConfig</namespace>
+ <mergestrategy>merge</mergestrategy>
+ </_config>
+</configuration> \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.yaml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.yaml
new file mode 100644
index 0000000000..ee85a0c68d
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationForNodeConfig/config.yaml
@@ -0,0 +1,8 @@
+artifact:
+ name:
+ allowedChar: "a-zA-Z_0-9"
+ encoded: true
+ consumer: "appc,catalog"
+_config:
+ namespace: "NotificationForNodeConfig"
+ mergestrategy: "override" \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config-NS.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config-NS.properties
new file mode 100644
index 0000000000..279d407664
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config-NS.properties
@@ -0,0 +1,13 @@
+artifact.name.maxlength=14
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.supportedEncryption=MD5
+artifact.name.allowedChar=a-zA-Z
+artifact.name.allowedchar=a-zA-Z
+artifact.status=deleted
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorsList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=NotificationOnPropVal \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.json
new file mode 100644
index 0000000000..fc7f2347aa
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.json
@@ -0,0 +1,9 @@
+{
+ "artifact": {
+ "name": { "minlength": "6" },
+ "extension": "pdf,tgz,xls"
+ },
+
+ "_config": { "mergeStrategy": "union","namespace":"NotificationOnPropVal" }
+
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.properties
new file mode 100644
index 0000000000..4daad19dcc
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.properties
@@ -0,0 +1,3 @@
+maxCachedBufferSize=1024
+artifact.maxsize=1024
+artifact.name.maxlength=28 \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.xml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.xml
new file mode 100644
index 0000000000..e3a24fbc32
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <artifact>
+ <name>
+ <maxlength>28</maxlength>
+ </name>
+ <extension>gz,tgz</extension>
+ <supportedencryption>Base64</supportedencryption>
+ <status>deleted</status>
+ <mandatory>
+ <name>true</name>
+ </mandatory>
+ </artifact>
+ <_config>
+ <namespace>NotificationOnPropVal</namespace>
+ <mergeStrategy>merge</mergeStrategy>
+ </_config>
+ </configuration> \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.yaml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.yaml
new file mode 100644
index 0000000000..7283df4ecb
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/NotificationOnPropVal/config.yaml
@@ -0,0 +1,9 @@
+
+ artifact:
+ name:
+ allowedChar: "a-zA-Z_0-9"
+ encoded: true
+ consumer: "appc,catalog"
+ _config:
+ mergeStrategy: "override"
+ namespace: "NotificationOnPropVal" \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.json
new file mode 100644
index 0000000000..42c6be91b9
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.json
@@ -0,0 +1,10 @@
+{
+
+ "artifact": {
+ "name": { "minlength": "6" },
+ "maxsize": "1048",
+ "extension": "pdf,tgz,xls"
+ },
+ "_config": { "mergeStrategy": "union","namespace":"SourceLocation" }
+
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.properties
new file mode 100644
index 0000000000..22c9840fad
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.properties
@@ -0,0 +1,14 @@
+artifact.name.maxlength=14
+artifact.maxsize=
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.supportedEncryption=MD5
+artifact.name.allowedChar=a-zA-Z
+artifact.name.allowedchar=a-zA-Z
+artifact.status=deleted
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorsList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=SourceLocation \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.xml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.xml
new file mode 100644
index 0000000000..1162af576e
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <artifact>
+ <name>
+ <maxlength>28</maxlength>
+ </name>
+ <maxsize>1048576</maxsize>
+ <extension>gz,tgz</extension>
+ <supportedencryption>Base64</supportedencryption>
+ <status>deleted</status>
+ <mandatory>
+ <name>true</name>
+ </mandatory>
+ </artifact>
+ <_config>
+ <namespace>SourceLocation</namespace>
+ <mergeStrategy>merge</mergeStrategy>
+ </_config>
+</configuration> \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.yaml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.yaml
new file mode 100644
index 0000000000..4e073ce7f9
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/SourceLocation/appjarconfig.yaml
@@ -0,0 +1,8 @@
+artifact:
+ name:
+ allowedChar: "a-zA-Z_0-9"
+ encoded: true
+ consumer: "appc,catalog"
+_config:
+ mergeStrategy: "override"
+ namespace: "SourceLocation" \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config-NS.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config-NS.properties
new file mode 100644
index 0000000000..40b4518945
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config-NS.properties
@@ -0,0 +1,13 @@
+artifact.name.maxlength=14
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.supportedEncryption=MD5
+artifact.name.allowedChar=a-zA-Z
+artifact.name.allowedchar=a-zA-Z
+artifact.status=deleted
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorsList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=UnregisterNotification \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.json
new file mode 100644
index 0000000000..3e0464016d
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.json
@@ -0,0 +1,9 @@
+{
+ "artifact": {
+ "name": { "minlength": "6" },
+ "extension": "pdf,tgz,xls"
+ },
+
+ "_config": { "mergeStrategy": "union","namespace":"UnregisterNotification" }
+
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.properties
new file mode 100644
index 0000000000..4daad19dcc
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.properties
@@ -0,0 +1,3 @@
+maxCachedBufferSize=1024
+artifact.maxsize=1024
+artifact.name.maxlength=28 \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.xml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.xml
new file mode 100644
index 0000000000..1153658161
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <artifact>
+ <name>
+ <maxlength>28</maxlength>
+ </name>
+ <extension>gz,tgz</extension>
+ <supportedencryption>Base64</supportedencryption>
+ <status>deleted</status>
+ <mandatory>
+ <name>true</name>
+ </mandatory>
+ </artifact>
+ <_config>
+ <namespace>UnregisterNotification</namespace>
+ <mergeStrategy>merge</mergeStrategy>
+ </_config>
+ </configuration> \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.yaml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.yaml
new file mode 100644
index 0000000000..1deb37ac7a
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/UnregisterNotification/config.yaml
@@ -0,0 +1,9 @@
+
+ artifact:
+ name:
+ allowedChar: "a-zA-Z_0-9"
+ encoded: true
+ consumer: "appc,catalog"
+ _config:
+ mergeStrategy: "override"
+ namespace: "UnregisterNotification" \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateDefaultMode/config-defaultmode.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateDefaultMode/config-defaultmode.json
new file mode 100644
index 0000000000..72833024c4
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateDefaultMode/config-defaultmode.json
@@ -0,0 +1,8 @@
+{
+ "artifact": {
+ "name": {
+ "minlength": "6"
+ },
+ "extension": "pdf,tgz,xls"
+ }
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateDefaultMode/config-defaultmode.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateDefaultMode/config-defaultmode.properties
new file mode 100644
index 0000000000..c857da38e9
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateDefaultMode/config-defaultmode.properties
@@ -0,0 +1,2 @@
+artifact.name.maxlength=14
+artifact.maxsize=1048 \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateNodeConfig/config-NS.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateNodeConfig/config-NS.properties
new file mode 100644
index 0000000000..a782e25835
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateNodeConfig/config-NS.properties
@@ -0,0 +1,13 @@
+artifact.name.maxlength=14
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.supportedEncryption=MD5
+artifact.name.allowedChar=a-zA-Z
+artifact.name.allowedchar=a-zA-Z
+artifact.status=deleted
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorsList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=ValidateNodeConfig \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateNodeConfig/config.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateNodeConfig/config.properties
new file mode 100644
index 0000000000..4daad19dcc
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/ValidateNodeConfig/config.properties
@@ -0,0 +1,3 @@
+maxCachedBufferSize=1024
+artifact.maxsize=1024
+artifact.name.maxlength=28 \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config-M.xml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config-M.xml
new file mode 100644
index 0000000000..320e53348d
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config-M.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <artifact>
+ <name>
+ <maxlength>28</maxlength>
+ </name>
+ <maxsize>1048576</maxsize>
+ <extension>gz,tgz</extension>
+ <supportedencryption>Base64</supportedencryption>
+ <status>deleted</status>
+ <mandatory>
+ <name>true</name>
+ </mandatory>
+ </artifact>
+ <_config>
+ <namespace>XMLConfig</namespace>
+ <mergeStrategy>merge</mergeStrategy>
+ </_config>
+</configuration> \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config-O.xml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config-O.xml
new file mode 100644
index 0000000000..508c920b83
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config-O.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <artifact>
+ <name>
+ <allowedChar>a-zA-Z_0-9</allowedChar>
+ </name>
+ <encoded>true</encoded>
+ <consumer>appc,catalog</consumer>
+ </artifact>
+ <_config>
+ <namespace>XMLConfig</namespace>
+ <mergeStrategy>override</mergeStrategy>
+ </_config>
+</configuration> \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config-U.xml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config-U.xml
new file mode 100644
index 0000000000..962bd342f3
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config-U.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <artifact>
+ <name>
+ <minlength>6</minlength>
+ </name>
+ <maxsize>1048</maxsize>
+ <extension>pdf,tgz,xls</extension>
+ </artifact>
+ <_config>
+ <namespace>XMLConfig</namespace>
+ <mergeStrategy>union</mergeStrategy>
+ </_config>
+</configuration> \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config.xml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config.xml
new file mode 100644
index 0000000000..2fff65b2e0
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/XMLConfiguration/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <artifact>
+ <name>
+ <maxlength>14</maxlength>
+ <allowedChar>a-zA-Z</allowedChar>
+ <allowedchar>a-zA-Z</allowedchar>
+ </name>
+ <!-- <maxsize></maxsize>-->
+ <extension>pdf</extension>
+ <extension>zip,xml</extension>
+
+ <supportedEncryption>Base64</supportedEncryption>
+ <supportedEncryption>MD5</supportedEncryption>
+ <status>deleted</status>
+ <status>Deleted</status>
+ <persistLocation>/opt/spool,${sys:user.home}/asdc</persistLocation>
+ <jsonSchema>@GeneratorList.json</jsonSchema>
+ <xmlSchema>@${env:path}/myschema.json</xmlSchema>
+ <consumerAPPC>${artifact.consumer}</consumerAPPC>
+ </artifact>
+ <_config>
+ <namespace>XMLConfig</namespace>
+ </_config>
+</configuration> \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config-M.yaml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config-M.yaml
new file mode 100644
index 0000000000..8ff08cdc43
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config-M.yaml
@@ -0,0 +1,12 @@
+ artifact:
+ name:
+ maxlength: 28
+ maxsize: 1048576
+ extension: "gz,tgz"
+ supportedencryption: Base64
+ status: deleted
+ mandatory:
+ name: true
+ _config:
+ namespace: YAMLConfig
+ mergeStrategy: merge \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config-O.yaml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config-O.yaml
new file mode 100644
index 0000000000..051d41d76b
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config-O.yaml
@@ -0,0 +1,8 @@
+ artifact:
+ name:
+ allowedChar: "a-zA-Z_0-9"
+ encoded: true
+ consumer: "appc,catalog"
+ _config:
+ namespace: YAMLConfig
+ mergeStrategy: override \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config-U.yaml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config-U.yaml
new file mode 100644
index 0000000000..8a9ab0e13e
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config-U.yaml
@@ -0,0 +1,8 @@
+ artifact:
+ name:
+ minlength: 6
+ maxsize: 1048
+ extension: "pdf,tgz,xls"
+ _config:
+ namespace: YAMLConfig
+ mergeStrategy: union \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config.yaml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config.yaml
new file mode 100644
index 0000000000..706b22db5e
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/YAMLConfiguration/config.yaml
@@ -0,0 +1,27 @@
+artifact:
+ name:
+ maxlength: 14
+ allowedChar: "a-zA-Z"
+ allowedchar: "a-zA-Z"
+ #maxsize: ""
+ extension:
+ -
+ pdf
+ -
+ zip,xml
+ supportedEncryption:
+ -
+ Base64
+ -
+ MD5
+ status:
+ -
+ deleted
+ -
+ Deleted
+ persistLocation: "/opt/spool,${sys:user.home}/asdc"
+ jsonSchema: "@GeneratorList.json"
+ xmlSchema: "@${env:path}/myschema.json"
+ consumerAPPC: "${artifact.consumer}"
+_config:
+ namespace: YAMLConfig \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/config-system.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/config-system.properties
new file mode 100644
index 0000000000..cfe91e6c7d
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/config-system.properties
@@ -0,0 +1,22 @@
+driverClassName=com.github.adejanovski.cassandra.jdbc.CassandraDriver
+jdbcURL=jdbc:${dbname}://${dbhost}:${dbport}/${configdb}
+dbuser=
+dbpassword=
+config.Table=configuration
+config.monitor.Table=configuration_change
+configKey=key
+configValue=value
+configNameColumn=name
+configdb=dox
+dbhost=
+dbport=9042
+dbname=cassandra
+createtablecql=create table if not exists ${configdb}.${config.Table} (name text\, key text\, value text\, PRIMARY KEY (name\, key)) with clustering order by (key asc)
+createmonitoringtablecql=create table if not exists ${configdb}.${config.monitor.Table} (name text\, changed_when bigint\, key text\, old_value text\, new_value text\, PRIMARY KEY (name\, changed_when)) with clustering order by (changed_when desc)
+insertconfigurationchangecql=insert into ${configdb}.${config.monitor.Table} (name\, changed_when\, key\, old_value\, new_value) values(?\, ?\, ?\, ?\, ?)
+fetchkeysql=select ${configKey} from ${config.Table} where ${configNameColumn}=?
+fetchlastchangecql=select changed_when from ${configdb}.${config.monitor.Table} where name=? limit 1
+fetchnamescql=select distinct name from ${configdb}.${config.Table}
+config.size.max=100
+config.refresh.interval=30000
+event.fetch.delay=5000 \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback-merge.xml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback-merge.xml
new file mode 100644
index 0000000000..3595efd87b
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback-merge.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <artifact>
+ <name>
+ <maxlength>28</maxlength>
+ </name>
+ <maxsize>1048576</maxsize>
+ <extension>gz,tgz</extension>
+ <supportedencryption>Base64</supportedencryption>
+ <status>deleted</status>
+ <mandatory>
+ <name>true</name>
+ </mandatory>
+ </artifact>
+</configuration> \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback-override.json b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback-override.json
new file mode 100644
index 0000000000..dd6087b70c
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback-override.json
@@ -0,0 +1,7 @@
+{
+ "artifact": {
+ "name": { "allowedChar": "a-zA-Z_0-9" },
+ "encoded": "true",
+ "consumer": "appc,catalog"
+ }
+} \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback-union.yaml b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback-union.yaml
new file mode 100644
index 0000000000..957b75d40a
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback-union.yaml
@@ -0,0 +1,5 @@
+ artifact:
+ name:
+ minlength: 6
+ maxsize: 1048
+ extension: "pdf,tgz,xls" \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback.properties
new file mode 100644
index 0000000000..7839839258
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/fallback/config-fallback.properties
@@ -0,0 +1,13 @@
+artifact.name.maxlength=14
+#artifact.maxsize=
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.supportedEncryption=MD5
+artifact.name.allowedChar=a-zA-Z
+artifact.name.allowedchar=a-zA-Z
+artifact.status=deleted
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config-M.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config-M.properties
new file mode 100644
index 0000000000..8a571ebc89
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config-M.properties
@@ -0,0 +1,7 @@
+artifact.name.maxlength=28
+artifact.maxsize=1048576
+artifact.extension=gz, tgz
+artifact.supportedencryption=Base64
+artifact.mandatory.name=true
+_config.namespace=javaProperties
+_config.mergeStrategy=merge \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config-O.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config-O.properties
new file mode 100644
index 0000000000..b27c67a78d
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config-O.properties
@@ -0,0 +1,5 @@
+artifact.name.allowedChar=a-zA-Z_0-9
+artifact.encoded=true
+artifact.consumer=appc, catalog
+_config.namespace=javaProperties
+_config.mergeStrategy=override \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config-U.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config-U.properties
new file mode 100644
index 0000000000..615f2a2093
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config-U.properties
@@ -0,0 +1,5 @@
+artifact.maxsize=1048
+artifact.extension=pdf,tgz, xls
+artifact.name.minlength=6
+_config.namespace=javaProperties
+_config.mergeStrategy=union \ No newline at end of file
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config.properties
new file mode 100644
index 0000000000..d9051f6ec4
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/java-properties/config.properties
@@ -0,0 +1,14 @@
+artifact.name.maxlength=14
+#artifact.maxsize=
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.supportedEncryption=MD5
+artifact.name.allowedChar=a-zA-Z
+artifact.name.allowedchar=a-zA-Z
+artifact.status=deleted
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=javaProperties
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config-at.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config-at.properties
new file mode 100644
index 0000000000..3bc773369b
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config-at.properties
@@ -0,0 +1,11 @@
+artifact.name.maxlength=20
+#artifact.maxsize=
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.name.allowedChar=a-zA-Z
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=OPENECOMP:tenancy
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config-tf.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config-tf.properties
new file mode 100644
index 0000000000..196bafe4e4
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config-tf.properties
@@ -0,0 +1,10 @@
+artifact.name.maxlength=30
+#artifact.maxsize=
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.name.allowedChar=a-zA-Z
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=Telefonica:tenancy
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config-vf.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config-vf.properties
new file mode 100644
index 0000000000..4c0c6ad897
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config-vf.properties
@@ -0,0 +1,11 @@
+artifact.name.maxlength=24
+#artifact.maxsize=
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.name.allowedChar=a-zA-Z
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=Vodafone:tenancy
diff --git a/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config.properties b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config.properties
new file mode 100644
index 0000000000..8ed2485dc2
--- /dev/null
+++ b/common/onap-common-configuration-management/onap-configuration-management-test/src/test/resources/multitenancy/config.properties
@@ -0,0 +1,11 @@
+artifact.name.maxlength=14
+#artifact.maxsize=
+artifact.extension=pdf, zip, xml
+artifact.supportedEncryption=Base64
+artifact.name.allowedChar=a-zA-Z
+artifact.status=Deleted
+artifact.persistLocation=/opt/spool, ${sys:user.home}/asdc
+artifact.jsonSchema=@GeneratorList.json
+artifact.xmlSchema=@${env:path}/myschema.json
+artifact.consumerAPPC=${artifact.consumer}
+_config.namespace=tenancy
diff --git a/common/onap-common-configuration-management/pom.xml b/common/onap-common-configuration-management/pom.xml
new file mode 100644
index 0000000000..56f4b5eea5
--- /dev/null
+++ b/common/onap-common-configuration-management/pom.xml
@@ -0,0 +1,30 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <name>onap-common-configuration-management</name>
+ <groupId>org.onap.sdc.common</groupId>
+ <artifactId>onap-common-configuration-management</artifactId>
+ <packaging>pom</packaging>
+
+ <parent>
+ <groupId>org.onap.sdc.common</groupId>
+ <artifactId>onap-common-lib</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <modules>
+ <module>onap-configuration-management-api</module>
+ <module>onap-configuration-management-core</module>
+ <module>onap-configuration-management-test</module>
+ </modules>
+
+<repositories>
+ <repository>
+ <id>java.net</id>
+ <url>http://repo1.maven.org/maven2</url>
+ </repository>
+</repositories>
+
+</project>