add periodic fetch configuration 24/99924/10
authorlukai <lukai@chinamobile.com>
Fri, 27 Dec 2019 02:02:14 +0000 (10:02 +0800)
committerLUKAI <lukai@chinamobile.com>
Wed, 8 Jan 2020 02:50:27 +0000 (02:50 +0000)
Issue-ID: DCAEGEN2-2007

Signed-off-by: Kai Lu <lukai@chinamobile.com>
Change-Id: Iab1c329534e37323eb7d0f1227b2d5c16e1cb50c

dcae-analytics/dcae-analytics-model/pom.xml
dcae-analytics/dcae-analytics-model/src/main/java/org/onap/dcae/analytics/model/configbindingservice/ConfigBindingServiceConstants.java
dcae-analytics/dcae-analytics-model/src/main/java/org/onap/dcae/analytics/model/util/supplier/ConfigBindingServiceJsonSupplier.java [deleted file]
dcae-analytics/dcae-analytics-web/src/main/java/org/onap/dcae/analytics/web/config/SystemConfig.java [new file with mode: 0644]
dcae-analytics/dcae-analytics-web/src/main/java/org/onap/dcae/analytics/web/exception/EnvironmentLoaderException.java [new file with mode: 0644]
dcae-analytics/dcae-analytics-web/src/main/java/org/onap/dcae/analytics/web/spring/ConfigBindingServiceEnvironmentPostProcessor.java
dcae-analytics/dcae-analytics-web/src/test/java/org/onap/dcae/analytics/web/spring/ConfigBindingServiceEnvironmentPostProcessorTest.java [deleted file]

index b16958a..337dcb4 100644 (file)
     <name>DCAE Analytics Model</name>
     <description>Contains models (e.g. Common Event Format) which are common to DCAE Analytics</description>
 
-    <properties>
-        <main.basedir>${project.parent.basedir}</main.basedir>
-    </properties>
+       <properties>
+               <main.basedir>${project.parent.basedir}</main.basedir>
+               <sdk.version>1.1.6</sdk.version>
+               <immutable.version>2.7.1</immutable.version>
+       </properties>
 
     <dependencies>
 
             <artifactId>dcae-analytics-test</artifactId>
         </dependency>
 
-    </dependencies>
+       <dependency>
+               <groupId>org.onap.dcaegen2.services.sdk.rest.services</groupId>
+               <artifactId>cbs-client</artifactId>
+               <version>${sdk.version}</version>
+       </dependency>
+       <dependency>
+               <groupId>org.onap.dcaegen2.services.sdk.rest.services</groupId>
+               <artifactId>dmaap-client</artifactId>
+               <version>${sdk.version}</version>
+       </dependency>
+       <dependency>
+               <groupId>org.onap.dcaegen2.services.sdk.rest.services</groupId>
+               <artifactId>common-dependency</artifactId>
+               <version>${sdk.version}</version>
+       </dependency>
+       <dependency>
+               <groupId>org.springframework</groupId>
+               <artifactId>spring-beans</artifactId>
+       </dependency>
+       <dependency>
+               <groupId>org.springframework</groupId>
+               <artifactId>spring-context</artifactId>
+       </dependency>
+       <dependency>
+               <groupId>org.springframework</groupId>
+               <artifactId>spring-webflux</artifactId>
+       </dependency>
+       <dependency>
+               <groupId>org.springframework.boot</groupId>
+               <artifactId>spring-boot-autoconfigure</artifactId>
+       </dependency>
+       <dependency>
+               <groupId>javax.validation</groupId>
+               <artifactId>validation-api</artifactId>
+       </dependency>
+        <dependency>
+                <groupId>org.immutables</groupId>
+                <artifactId>value</artifactId>
+                <version>${immutable.version}</version>
+                <scope>provided</scope>
+        </dependency>
+
+       </dependencies>
 
 </project>
index 786765f..9776d70 100644 (file)
@@ -34,6 +34,7 @@ public abstract class ConfigBindingServiceConstants {
 
     // ================== CONFIG SERVICE CONSTANTS ============================== //
     public static final String CONSUL_HOST_ENV_VARIABLE_KEY = "CONSUL_HOST";
+    public static final Integer DEFAULT_CONSUL_PORT_ENV_VARIABLE_VALUE = 8500;
     public static final String CONSUL_HOST_ENV_VARIABLE_VALUE = System.getenv(CONSUL_HOST_ENV_VARIABLE_KEY);
     public static final String CONFIG_BINDING_SERVICE_ENV_VARIABLE_KEY = "CONFIG_BINDING_SERVICE";
     public static final String CONFIG_BINDING_SERVICE_ENV_VARIABLE_VALUE =
@@ -47,12 +48,13 @@ public abstract class ConfigBindingServiceConstants {
 
     public static final String CONFIG_BINDING_SERVICE_PROPERTIES_KEY = "config-binding-service";
 
-
     public static final Set<String> SPRING_RESERVED_PROPERTIES_KEY_PREFIXES =
             Stream.of("spring", "endpoints", "server", "logging", "management").collect(Collectors.toSet());
     public static final String CONFIG_SERVICE_MESSAGE_ROUTER_VALUE = "message_router";
     // CONVERT JSON TO MAP
     public static final String KEY_SEPARATOR = ".";
+    public static final String CONFIG = "config";
+    public static final int CONFIG_SERVICE_REFRESHPERIOD = 1;
 
     // ============== CONFIG BINDING SERVICE UTILS ========================= //
     /**
diff --git a/dcae-analytics/dcae-analytics-model/src/main/java/org/onap/dcae/analytics/model/util/supplier/ConfigBindingServiceJsonSupplier.java b/dcae-analytics/dcae-analytics-model/src/main/java/org/onap/dcae/analytics/model/util/supplier/ConfigBindingServiceJsonSupplier.java
deleted file mode 100644 (file)
index b882bb0..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * ================================================================================
- * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- *
- */
-
-package org.onap.dcae.analytics.model.util.supplier;
-
-
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Function;
-import java.util.function.Supplier;
-
-import org.onap.dcae.analytics.model.configbindingservice.ConfigBindingServiceConstants;
-import org.onap.dcae.analytics.model.configbindingservice.ConsulConfigBindingServiceQueryResponse;
-import org.onap.dcae.analytics.model.util.function.StringToURLFunction;
-import org.onap.dcae.analytics.model.util.function.URLToHttpGetFunction;
-import org.onap.dcae.analytics.model.util.json.AnalyticsModelJsonConversion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A Function which fetches ApplicationProperties configuration from
- * Config Binding Service when deployed via docker, typically during application startup time.
- *
- * @author Rajiv Singla
- */
-public class ConfigBindingServiceJsonSupplier implements Supplier<Optional<String>> {
-
-    private static final Logger logger = LoggerFactory.getLogger(ConfigBindingServiceJsonSupplier.class);
-
-    private final Function<String, Optional<String>> fetchUrlContentFunction;
-
-    public ConfigBindingServiceJsonSupplier(final Function<String, Optional<String>> fetchUrlContentFunction) {
-        this.fetchUrlContentFunction = fetchUrlContentFunction;
-    }
-
-    public ConfigBindingServiceJsonSupplier() {
-        fetchUrlContentFunction = (String s) -> new StringToURLFunction().apply(s).flatMap(new URLToHttpGetFunction());
-    }
-
-    @Override
-    public Optional<String> get() {
-
-        logger.info("Consul Host Environment Variable: {}",
-                ConfigBindingServiceConstants.CONSUL_HOST_ENV_VARIABLE_VALUE);
-        logger.info("Config Binding Service Environment Variable: {}",
-                ConfigBindingServiceConstants.CONFIG_BINDING_SERVICE_ENV_VARIABLE_VALUE);
-        logger.info("Service Name Environment Variable: {}",
-                ConfigBindingServiceConstants.SERVICE_NAME_ENV_VARIABLE_VALUE);
-
-        if (ConfigBindingServiceConstants.CONSUL_HOST_ENV_VARIABLE_VALUE == null ||
-                ConfigBindingServiceConstants.CONFIG_BINDING_SERVICE_ENV_VARIABLE_VALUE == null ||
-                ConfigBindingServiceConstants.SERVICE_NAME_ENV_VARIABLE_VALUE == null) {
-            logger.error("Environment variables required to query Config Binding Service are not present");
-            return Optional.empty();
-        }
-
-        return Optional.of(ConfigBindingServiceConstants.CONSUL_QUERY_URL_STRING)
-                // Step 1: Query CONSUL to get the IP/PORT of CONFIG BINDING SERVICE
-                .flatMap(fetchUrlContentFunction)
-                // Step 2: Fetch the generated configurations from CONFIG BINDING SERVICE
-                .flatMap(ConfigBindingServiceJsonSupplier::parseConsulConfigBindingServiceQueryResponseJson)
-                // Step 3: create url from service address and service port
-                .flatMap(ConfigBindingServiceJsonSupplier::createConfigServiceURL)
-                // Step 4: Fetch final config binding service generated application configuration json string
-                .flatMap(fetchUrlContentFunction);
-    }
-
-    /**
-     * Creates URL using config binding service ip address and port
-     *
-     * @param consulConfigBindingServiceQueryResponse consul config binding service query response containing config
-     * binding service address and service port
-     *
-     * @return config service url to fetch service configuration
-     */
-    private static Optional<String> createConfigServiceURL(final ConsulConfigBindingServiceQueryResponse
-                                                                   consulConfigBindingServiceQueryResponse) {
-        final String configBindingServiceAddress = consulConfigBindingServiceQueryResponse.getServiceAddress();
-        final Integer configServicePort = consulConfigBindingServiceQueryResponse.getServicePort();
-
-        if (configBindingServiceAddress == null && configServicePort == null) {
-            logger.error("Config Binding Service Address & Port are not present.");
-            return Optional.empty();
-        }
-
-        return Optional.of(String.format(ConfigBindingServiceConstants.CONFIG_SERVICE_QUERY_URL_STRING,
-                configBindingServiceAddress, configServicePort,
-                ConfigBindingServiceConstants.SERVICE_NAME_ENV_VARIABLE_VALUE));
-
-    }
-
-    private static Optional<ConsulConfigBindingServiceQueryResponse>
-    parseConsulConfigBindingServiceQueryResponseJson(final String configBindingServiceQueryResponseJson) {
-        // parse json
-        final Optional<List<ConsulConfigBindingServiceQueryResponse>> configBindingServiceQueryResponseOptional =
-                AnalyticsModelJsonConversion.CONFIG_BINDING_SERVICE_LIST_JSON_FUNCTION
-                        .apply(configBindingServiceQueryResponseJson);
-
-        // check parsing is successful and at least 1 config binding query response is present
-        if (!configBindingServiceQueryResponseOptional.isPresent() ||
-                configBindingServiceQueryResponseOptional.get().isEmpty()) {
-            logger.error("No Consul config binding service information found in JSON: {} ",
-                    configBindingServiceQueryResponseJson);
-            return Optional.empty();
-        }
-
-        // return first consul query response
-        return Optional.of(configBindingServiceQueryResponseOptional.get().get(0));
-    }
-
-
-}
diff --git a/dcae-analytics/dcae-analytics-web/src/main/java/org/onap/dcae/analytics/web/config/SystemConfig.java b/dcae-analytics/dcae-analytics-web/src/main/java/org/onap/dcae/analytics/web/config/SystemConfig.java
new file mode 100644 (file)
index 0000000..946c2f2
--- /dev/null
@@ -0,0 +1,84 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2019-2020 China Mobile.  All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package org.onap.dcae.analytics.web.config;
+
+import java.util.Optional;
+
+import org.onap.dcae.analytics.model.configbindingservice.ConfigBindingServiceConstants;
+import org.onap.dcae.analytics.web.exception.EnvironmentLoaderException;
+
+/**
+ * 
+ * get consul config and cbs config.
+ *
+ * @author Kai Lu
+ */
+public class SystemConfig {
+
+    /**
+     * 
+     * private constructor.
+     *
+     */
+    private SystemConfig() {
+    }
+
+    /**
+     * getConsulHost.
+     *
+     * @return consulHost consulHost
+     *
+     */
+    public static String getConsulHost() throws EnvironmentLoaderException {
+        return Optional.ofNullable(ConfigBindingServiceConstants.CONSUL_HOST_ENV_VARIABLE_VALUE)
+                .orElseThrow(() -> new EnvironmentLoaderException("$CONSUL_HOST environment has not been defined"));
+    }
+
+    /**
+     * getConsultPort.
+     *
+     * @return consulPort consulPort
+     *
+     */
+    public static Integer getConsultPort() {
+        return ConfigBindingServiceConstants.DEFAULT_CONSUL_PORT_ENV_VARIABLE_VALUE;
+    }
+
+    /**
+     * getConfigBindingService.
+     *
+     * @return configBindingService configBindingService
+     *
+     */
+    public static String getConfigBindingService() throws EnvironmentLoaderException {
+        return Optional.ofNullable(ConfigBindingServiceConstants.CONFIG_BINDING_SERVICE_ENV_VARIABLE_VALUE) //
+                .orElseThrow(() -> new EnvironmentLoaderException(
+                        "$CONFIG_BINDING_SERVICE environment has not been defined"));
+    }
+
+    /**
+     * getService.
+     *
+     * @return service service
+     *
+     */
+    public static String getService() throws EnvironmentLoaderException {
+        return Optional.ofNullable(ConfigBindingServiceConstants.SERVICE_NAME_ENV_VARIABLE_VALUE).orElseThrow(
+                () -> new EnvironmentLoaderException("$HOSTNAME have not been defined as system environment"));
+    }
+
+}
diff --git a/dcae-analytics/dcae-analytics-web/src/main/java/org/onap/dcae/analytics/web/exception/EnvironmentLoaderException.java b/dcae-analytics/dcae-analytics-web/src/main/java/org/onap/dcae/analytics/web/exception/EnvironmentLoaderException.java
new file mode 100644 (file)
index 0000000..0a5c14d
--- /dev/null
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019-2020 China Mobile. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.dcae.analytics.web.exception;
+
+/**
+ * Exception thrown when there is a problem with the Consul environment.
+ *
+ * @author Kai Lu
+ */
+public class EnvironmentLoaderException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    public EnvironmentLoaderException(String message) {
+        super(message);
+    }
+}
index 2073127..59fca64 100644 (file)
@@ -19,6 +19,7 @@
 
 package org.onap.dcae.analytics.web.spring;
 
+import java.time.Duration;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Map;
@@ -29,8 +30,16 @@ import java.util.stream.Collectors;
 import org.onap.dcae.analytics.model.AnalyticsProfile;
 import org.onap.dcae.analytics.model.configbindingservice.ConfigBindingServiceConstants;
 import org.onap.dcae.analytics.model.util.function.JsonStringToMapFunction;
-import org.onap.dcae.analytics.model.util.supplier.ConfigBindingServiceJsonSupplier;
+import org.onap.dcae.analytics.web.config.SystemConfig;
 import org.onap.dcae.analytics.web.exception.AnalyticsValidationException;
+import org.onap.dcae.analytics.web.exception.EnvironmentLoaderException;
+import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsClient;
+import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsClientFactory;
+import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsRequests;
+import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.CbsRequest;
+import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.EnvProperties;
+import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.ImmutableEnvProperties;
+import org.onap.dcaegen2.services.sdk.rest.services.model.logging.RequestDiagnosticContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.boot.SpringApplication;
@@ -44,6 +53,13 @@ import org.springframework.core.env.StandardEnvironment;
 import org.springframework.util.ClassUtils;
 import org.springframework.web.context.support.StandardServletEnvironment;
 
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+
+import reactor.core.Disposable;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
 /**
  * A custom spring framework environment post processor which can fetch and populate spring context with
  * Config Binding Service application properties.
@@ -60,63 +76,33 @@ public class ConfigBindingServiceEnvironmentPostProcessor implements Environment
 
     private static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE;
 
+    private Disposable refreshConfigTask = null;
+
+    private ConfigurableEnvironment env = null;
+
+    private Map<String, Object> filterKeyMap = null;
+
+    private String configServicePropertiesKey =
+            ConfigBindingServiceConstants.CONFIG_BINDING_SERVICE_PROPERTIES_KEY;
+
     @Override
-    public void postProcessEnvironment(final ConfigurableEnvironment environment, final SpringApplication application) {
+    public void postProcessEnvironment(final ConfigurableEnvironment environment,
+            final SpringApplication application) {
 
         final boolean isConfigServiceProfilePresent = Arrays.stream(environment.getActiveProfiles())
                 .anyMatch(p -> p.equalsIgnoreCase(AnalyticsProfile.CONFIG_BINDING_SERVICE_PROFILE_NAME));
 
         if (!isConfigServiceProfilePresent) {
-            logger.info("Config Binding Service Profile is not active. " +
-                    "Skipping Adding config binding service properties");
+            logger.info("Config Binding Service Profile is not active. "
+                    "Skipping Adding config binding service properties");
             return;
         }
 
-        logger.info("Config Binding Service Profile is active. " +
-                "Application properties will be fetched from config binding service");
-
-        // Fetch config binding service json
-        final Optional<String> configServiceJsonOptional = new ConfigBindingServiceJsonSupplier().get();
+        logger.info("Config Binding Service Profile is active. "
+                + "Application properties will be fetched from config binding service");
 
-        if (!configServiceJsonOptional.isPresent()) {
-            final String errorMessage = "Unable to get fetch application configuration from config binding service";
-            throw new AnalyticsValidationException(errorMessage, new IllegalStateException(errorMessage));
-        }
-
-        final String configServicePropertiesKey = ConfigBindingServiceConstants.CONFIG_BINDING_SERVICE_PROPERTIES_KEY;
-
-        // convert fetch config binding service json string to Map of property key and values
-        final Map<String, Object> configPropertiesMap = configServiceJsonOptional
-                .map(new JsonStringToMapFunction(configServicePropertiesKey))
-                .orElse(Collections.emptyMap());
-
-        if (configPropertiesMap.isEmpty()) {
-
-            logger.warn("No properties found in config binding service");
-
-        } else {
-
-            // remove config service key prefix on spring reserved property key prefixes
-            final Set<String> springKeyPrefixes = ConfigBindingServiceConstants.SPRING_RESERVED_PROPERTIES_KEY_PREFIXES;
-            final Set<String> springKeys = springKeyPrefixes.stream()
-                    .map(springKeyPrefix -> configServicePropertiesKey + "." + springKeyPrefix)
-                    .collect(Collectors.toSet());
-
-            final Map<String, Object> filterKeyMap = configPropertiesMap.entrySet()
-                    .stream()
-                    .collect(Collectors.toMap(
-                            (Map.Entry<String, Object> e) ->
-                                    springKeys.stream().anyMatch(springKey -> e.getKey().startsWith(springKey)) ?
-                                            e.getKey().substring(configServicePropertiesKey.toCharArray().length + 1) :
-                                            e.getKey(),
-                            Map.Entry::getValue)
-                    );
-
-            filterKeyMap.forEach((key, value) ->
-                    logger.info("Adding property from config service in spring context: {} -> {}", key, value));
-
-            addJsonPropertySource(environment, new MapPropertySource(configServicePropertiesKey, filterKeyMap));
-        }
+        env = environment;
+        initialize();
 
     }
 
@@ -125,9 +111,8 @@ public class ConfigBindingServiceEnvironmentPostProcessor implements Environment
         return DEFAULT_ORDER;
     }
 
-
-    private void addJsonPropertySource(final ConfigurableEnvironment environment, final PropertySource<?> source) {
-        final MutablePropertySources sources = environment.getPropertySources();
+    public synchronized void addJsonPropertySource(final MutablePropertySources sources,
+            final PropertySource<?> source) {
         final String name = findPropertySource(sources);
         if (sources.contains(name)) {
             sources.addBefore(name, source);
@@ -137,12 +122,164 @@ public class ConfigBindingServiceEnvironmentPostProcessor implements Environment
     }
 
     private String findPropertySource(final MutablePropertySources sources) {
-        if (ClassUtils.isPresent(SERVLET_ENVIRONMENT_CLASS, null) &&
-                sources.contains(StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME)) {
+        if (ClassUtils.isPresent(SERVLET_ENVIRONMENT_CLASS, null)
+                && sources.contains(StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME)) {
             return StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME;
 
         }
         return StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME;
     }
 
+    /**
+     *
+     * Fetch the configuration.
+     *
+     */
+    public void initialize() {
+        stop();
+
+        refreshConfigTask = createRefreshTask() //
+                .subscribe(e -> logger.info("Refreshed configuration data"),
+                        throwable -> logger.error("Configuration refresh terminated due to exception", throwable),
+                        () -> logger.error("Configuration refresh terminated"));
+    }
+
+    /**
+     * Fetch the configuration task from CBS.
+     *
+     */
+    private Flux<String> createRefreshTask() {
+        return readEnvironmentVariables() //
+                .flatMap(this::createCbsClient) //
+                .flatMapMany(this::periodicConfigurationUpdates) //
+                .map(this::parseTcaConfig) //
+                .onErrorResume(this::onErrorResume);
+    }
+
+    /**
+     * periodicConfigurationUpdates.
+     *
+     * @param cbsClient cbsClient
+     * @return configuration refreshed
+     *
+     */
+    public Flux<JsonObject> periodicConfigurationUpdates(CbsClient cbsClient) {
+        final Duration initialDelay = Duration.ZERO;
+        final Duration refreshPeriod =
+                 Duration.ofMinutes(ConfigBindingServiceConstants.CONFIG_SERVICE_REFRESHPERIOD);
+        final CbsRequest getConfigRequest = CbsRequests.getAll(RequestDiagnosticContext.create());
+        return cbsClient.updates(getConfigRequest, initialDelay, refreshPeriod);
+    }
+
+    /**
+     *
+     * get environment variables.
+     *
+     * @return environment properties.
+     *
+     */
+    public Mono<EnvProperties> readEnvironmentVariables() {
+        logger.trace("Loading configuration from system environment variables");
+        EnvProperties envProperties;
+        try {
+            envProperties = ImmutableEnvProperties.builder() //
+                    .consulHost(SystemConfig.getConsulHost()) //
+                    .consulPort(SystemConfig.getConsultPort()) //
+                    .cbsName(SystemConfig.getConfigBindingService()) //
+                    .appName(SystemConfig.getService()) //
+                    .build();
+        } catch (EnvironmentLoaderException e) {
+            return Mono.error(e);
+        }
+        logger.trace("Evaluated environment system variables {}", envProperties);
+        return Mono.just(envProperties);
+    }
+
+    /**
+     * Stops the refreshing of the configuration.
+     *
+     */
+    public void stop() {
+        if (refreshConfigTask != null) {
+            refreshConfigTask.dispose();
+            refreshConfigTask = null;
+        }
+    }
+
+    /**
+     * periodicConfigurationUpdates.
+     *
+     * @param throwable throwable
+     * @return Mono
+     *
+     */
+    private <R> Mono<R> onErrorResume(Throwable throwable) {
+        logger.error("Could not refresh application configuration {}", throwable.toString());
+        return Mono.empty();
+    }
+
+    /**
+     * create CbsClient.
+     *
+     * @param env environment properties
+     * @return cbsclient
+     *
+     */
+    public Mono<CbsClient> createCbsClient(EnvProperties env) {
+        return CbsClientFactory.createCbsClient(env);
+    }
+
+    /**
+     * Parse configuration.
+     *
+     * @param jsonObject the TCA service's configuration
+     * @return this
+     *
+     */
+    public String parseTcaConfig(JsonObject jsonObject) {
+
+        JsonElement jsonConfig = jsonObject.get(ConfigBindingServiceConstants.CONFIG);
+
+        Optional<String> configServiceJsonOptional = Optional.of(jsonConfig.toString());
+        if (!configServiceJsonOptional.isPresent()) {
+            final String errorMessage =
+                    "Unable to get fetch application configuration from config binding service";
+            throw new AnalyticsValidationException(errorMessage,
+                    new IllegalStateException(errorMessage));
+        }
+
+        // convert fetch config binding service json string to Map of property key and
+        // values
+        Map<String, Object> configPropertiesMap = configServiceJsonOptional
+                .map(new JsonStringToMapFunction(configServicePropertiesKey)).orElse(Collections.emptyMap());
+
+        if (configPropertiesMap.isEmpty()) {
+
+            logger.warn("No properties found in config binding service");
+
+        } else {
+
+            // remove config service key prefix on spring reserved property key prefixes
+            final Set<String> springKeyPrefixes =
+                    ConfigBindingServiceConstants.SPRING_RESERVED_PROPERTIES_KEY_PREFIXES;
+            final Set<String> springKeys = springKeyPrefixes.stream()
+                    .map(springKeyPrefix -> configServicePropertiesKey + "." + springKeyPrefix)
+                    .collect(Collectors.toSet());
+
+            filterKeyMap = configPropertiesMap.entrySet().stream()
+                    .collect(Collectors.toMap((Map.Entry<String, Object> e) -> springKeys.stream()
+                            .anyMatch(springKey -> e.getKey().startsWith(springKey))
+                                    ? e.getKey().substring(configServicePropertiesKey.toCharArray().length + 1)
+                                    : e.getKey(),
+                            Map.Entry::getValue));
+
+            filterKeyMap.forEach((key, value) -> logger
+                    .info("Adding property from config service in spring context: {} -> {}", key, value));
+            MutablePropertySources sources = env.getPropertySources();
+            addJsonPropertySource(sources, new MapPropertySource(configServicePropertiesKey, filterKeyMap));
+
+        }
+        return configServiceJsonOptional.get();
+    }
+
 }
diff --git a/dcae-analytics/dcae-analytics-web/src/test/java/org/onap/dcae/analytics/web/spring/ConfigBindingServiceEnvironmentPostProcessorTest.java b/dcae-analytics/dcae-analytics-web/src/test/java/org/onap/dcae/analytics/web/spring/ConfigBindingServiceEnvironmentPostProcessorTest.java
deleted file mode 100644 (file)
index 5506342..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * ================================================================================
- * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- *
- */
-
-package org.onap.dcae.analytics.web.spring;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.mockito.Mockito;
-import org.onap.dcae.analytics.model.AnalyticsProfile;
-import org.onap.dcae.analytics.web.BaseAnalyticsWebTest;
-import org.onap.dcae.analytics.web.exception.AnalyticsValidationException;
-import org.springframework.boot.SpringApplication;
-import org.springframework.core.env.ConfigurableEnvironment;
-import org.springframework.core.env.MutablePropertySources;
-
-class ConfigBindingServiceEnvironmentPostProcessorTest extends BaseAnalyticsWebTest {
-
-    @BeforeAll
-    static void beforeAll() throws Exception {
-        BaseAnalyticsWebTest.initializeConfigBindingServiceEnvironmentVariables();
-    }
-
-
-    @Test
-    void postProcessEnvironment() {
-
-        Assertions.assertThrows(AnalyticsValidationException.class, () -> {
-
-            final ConfigBindingServiceEnvironmentPostProcessor configBindingServiceEnvironmentPostProcessor =
-                    new ConfigBindingServiceEnvironmentPostProcessor();
-
-            final ConfigurableEnvironment configurableEnvironment = Mockito.mock(ConfigurableEnvironment.class);
-            final SpringApplication springApplication = Mockito.mock(SpringApplication.class);
-            final String[] activeProfiles = {AnalyticsProfile.CONFIG_BINDING_SERVICE_PROFILE_NAME};
-            Mockito.when(configurableEnvironment.getActiveProfiles()).thenReturn(activeProfiles);
-
-            configBindingServiceEnvironmentPostProcessor
-                    .postProcessEnvironment(configurableEnvironment, springApplication);
-        });
-    }
-}