From 4117c9fd7fcea895e18872e0d541e0f14a9a41b9 Mon Sep 17 00:00:00 2001 From: grabinsk Date: Tue, 4 Jun 2019 15:18:44 +0200 Subject: fetching configuration from CBS at application bootstrap Change-Id: Ibaa56c38b87fc8b8cfa858f74b7bc201bd507b37 Issue-ID: DCAEGEN2-1544 Signed-off-by: grabinsk --- .../bootstrap/CbsBootstrapConfiguration.java | 57 +++++++++++++ .../bootstrap/CbsClientConfigurationResolver.java | 46 ++++++++++ .../services/bootstrap/CbsClientFactoryFacade.java | 34 ++++++++ .../bootstrap/CbsJsonToPropertyMapConverter.java | 64 ++++++++++++++ .../dcaegen2/services/bootstrap/CbsProperties.java | 98 ++++++++++++++++++++++ .../bootstrap/CbsPropertySourceLocator.java | 84 +++++++++++++++++++ .../services/bootstrap/RetryProperties.java | 54 ++++++++++++ .../org/onap/dcaegen2/services/prh/MainApp.java | 2 + .../configuration/CbsClientConfigFileReader.java | 60 ------------- .../CbsClientConfigurationResolver.java | 45 ---------- .../configuration/CbsConfigRefreshScheduler.java | 97 +++++++++++++++++++++ .../prh/configuration/CbsConfiguration.java | 37 +------- .../services/prh/configuration/PrhAppConfig.java | 13 +-- .../services/prh/tasks/ScheduledTasksRunner.java | 15 +--- .../src/main/resources/META-INF/spring.factories | 1 + prh-app-server/src/main/resources/application.yaml | 11 ++- prh-app-server/src/main/resources/bootstrap.yaml | 23 +++++ .../src/main/resources/cbs_client_config.json | 5 -- .../src/main/resources/logback-spring.xml | 7 +- 19 files changed, 579 insertions(+), 174 deletions(-) create mode 100644 prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsBootstrapConfiguration.java create mode 100644 prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsClientConfigurationResolver.java create mode 100644 prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsClientFactoryFacade.java create mode 100644 prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsJsonToPropertyMapConverter.java create mode 100644 prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsProperties.java create mode 100644 prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsPropertySourceLocator.java create mode 100644 prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/RetryProperties.java delete mode 100644 prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsClientConfigFileReader.java delete mode 100644 prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsClientConfigurationResolver.java create mode 100644 prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsConfigRefreshScheduler.java create mode 100644 prh-app-server/src/main/resources/META-INF/spring.factories create mode 100644 prh-app-server/src/main/resources/bootstrap.yaml delete mode 100644 prh-app-server/src/main/resources/cbs_client_config.json (limited to 'prh-app-server/src/main') diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsBootstrapConfiguration.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsBootstrapConfiguration.java new file mode 100644 index 00000000..0297a67a --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsBootstrapConfiguration.java @@ -0,0 +1,57 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2019 NOKIA 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.dcaegen2.services.bootstrap; + + +import org.onap.dcaegen2.services.prh.configuration.CbsConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableConfigurationProperties +public class CbsBootstrapConfiguration { + + @Bean + public CbsProperties cbsProperties() { + return new CbsProperties(); + } + + @Bean + @ConditionalOnProperty(value = "cbs.enabled", matchIfMissing = true) + public CbsPropertySourceLocator cbsPropertySourceLocator( + CbsProperties cbsProperties, + CbsConfiguration cbsConfiguration) { + + return new CbsPropertySourceLocator( + cbsProperties, + new CbsJsonToPropertyMapConverter(), + new CbsClientConfigurationResolver(cbsProperties), + new CbsClientFactoryFacade(), + cbsConfiguration); + } + + @Bean + public CbsConfiguration cbsConfiguration() { + return new CbsConfiguration(); + } +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsClientConfigurationResolver.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsClientConfigurationResolver.java new file mode 100644 index 00000000..41389980 --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsClientConfigurationResolver.java @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2019 NOKIA 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.dcaegen2.services.bootstrap; + +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.CbsClientConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class CbsClientConfigurationResolver { + + private static final Logger LOGGER = LoggerFactory.getLogger(CbsClientConfigurationResolver.class); + private final CbsProperties cbsProperties; + + CbsClientConfigurationResolver(CbsProperties cbsProperties) { + this.cbsProperties = cbsProperties; + } + + CbsClientConfiguration resolveCbsClientConfiguration() { + try { + return CbsClientConfiguration.fromEnvironment(); + } catch (Exception e) { + LOGGER.warn("Failed resolving CBS client configuration from system environments: " + e); + } + LOGGER.info("Falling back to use default CBS client configuration properties"); + return cbsProperties.toCbsClientConfiguration(); + } + +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsClientFactoryFacade.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsClientFactoryFacade.java new file mode 100644 index 00000000..a68a35c9 --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsClientFactoryFacade.java @@ -0,0 +1,34 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2019 NOKIA 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.dcaegen2.services.bootstrap; + +import org.jetbrains.annotations.NotNull; +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.model.CbsClientConfiguration; +import reactor.core.publisher.Mono; + +class CbsClientFactoryFacade { + @NotNull + Mono createCbsClient(CbsClientConfiguration cbsClientConfiguration) { + return CbsClientFactory.createCbsClient(cbsClientConfiguration); + } +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsJsonToPropertyMapConverter.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsJsonToPropertyMapConverter.java new file mode 100644 index 00000000..bf4077b9 --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsJsonToPropertyMapConverter.java @@ -0,0 +1,64 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2019 NOKIA 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.dcaegen2.services.bootstrap; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; + +import java.util.Map; +import java.util.stream.Collectors; + +class CbsJsonToPropertyMapConverter { + + private static final String CBS_CONFIG_ROOT_PROPERTY = "config"; + + Map convertToMap(JsonObject jsonObject) { + verifyExpectedCbsJsonFormat(jsonObject); + JsonObject config = jsonObject.getAsJsonObject(CBS_CONFIG_ROOT_PROPERTY); + return config.entrySet().stream().collect( + Collectors.toMap(Map.Entry::getKey, entry -> unpack(entry.getValue()))); + } + + private static void verifyExpectedCbsJsonFormat(JsonObject jsonObject) { + if (!jsonObject.has(CBS_CONFIG_ROOT_PROPERTY)) { + throw new IllegalArgumentException("Missing expected '" + CBS_CONFIG_ROOT_PROPERTY + "'" + + " property in json from CBS."); + } + } + + private Object unpack(JsonElement value) { + if (value.isJsonPrimitive()) { + JsonPrimitive primitiveValue = value.getAsJsonPrimitive(); + if (primitiveValue.isString()) { + return primitiveValue.getAsString(); + } + if (primitiveValue.isBoolean()) { + return primitiveValue.getAsBoolean(); + } + if (primitiveValue.isNumber()) { + return primitiveValue.getAsLong(); + } + } + return value; + } + +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsProperties.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsProperties.java new file mode 100644 index 00000000..18d4021b --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsProperties.java @@ -0,0 +1,98 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2019 NOKIA 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.dcaegen2.services.bootstrap; + + +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.CbsClientConfiguration; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.ImmutableCbsClientConfiguration; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; + +import java.time.Duration; + +@ConfigurationProperties("cbs") +public class CbsProperties { + + private Boolean enabled; + private Duration updatesInterval; + @NestedConfigurationProperty + private RetryProperties fetchRetries = new RetryProperties(); + private String hostname; + private Integer port; + private String appName; + + CbsClientConfiguration toCbsClientConfiguration() { + return ImmutableCbsClientConfiguration.builder() + .hostname(hostname) + .port(port) + .appName(appName) + .build(); + } + + public String getHostname() { + return hostname; + } + + public void setHostname(String hostname) { + this.hostname = hostname; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public Duration getUpdatesInterval() { + return updatesInterval; + } + + public void setUpdatesInterval(Duration updatesInterval) { + this.updatesInterval = updatesInterval; + } + + public RetryProperties getFetchRetries() { + return fetchRetries; + } + + public void setFetchRetries(RetryProperties fetchRetries) { + this.fetchRetries = fetchRetries; + } + +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsPropertySourceLocator.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsPropertySourceLocator.java new file mode 100644 index 00000000..7b660202 --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsPropertySourceLocator.java @@ -0,0 +1,84 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2019 NOKIA 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.dcaegen2.services.bootstrap; + +import com.google.gson.JsonObject; +import org.onap.dcaegen2.services.prh.configuration.CbsConfiguration; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsRequests; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.CbsClientConfiguration; +import org.onap.dcaegen2.services.sdk.rest.services.model.logging.RequestDiagnosticContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.bootstrap.config.PropertySourceLocator; +import org.springframework.core.env.Environment; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.PropertySource; + +import java.util.Map; + +public class CbsPropertySourceLocator implements PropertySourceLocator { + private static final Logger LOGGER = LoggerFactory.getLogger(CbsPropertySourceLocator.class); + + private final CbsProperties cbsProperties; + private final CbsJsonToPropertyMapConverter cbsJsonToPropertyMapConverter; + private final CbsClientConfigurationResolver cbsClientConfigurationResolver; + private final CbsClientFactoryFacade cbsClientFactoryFacade; + private final CbsConfiguration cbsConfiguration; + + public CbsPropertySourceLocator(CbsProperties cbsProperties, + CbsJsonToPropertyMapConverter cbsJsonToPropertyMapConverter, + CbsClientConfigurationResolver cbsClientConfigurationResolver, + CbsClientFactoryFacade cbsClientFactoryFacade, + CbsConfiguration cbsConfiguration) { + this.cbsProperties = cbsProperties; + this.cbsJsonToPropertyMapConverter = cbsJsonToPropertyMapConverter; + this.cbsClientConfigurationResolver = cbsClientConfigurationResolver; + this.cbsClientFactoryFacade = cbsClientFactoryFacade; + this.cbsConfiguration = cbsConfiguration; + } + + @Override + public PropertySource locate(Environment environment) { + CbsClientConfiguration cbsClientConfiguration = cbsClientConfigurationResolver.resolveCbsClientConfiguration(); + LOGGER.info("Fetching configuration from Config Binding Service @ {}:{} for {}", + cbsClientConfiguration.hostname(), cbsClientConfiguration.port(), cbsClientConfiguration.appName()); + Map properties = cbsClientFactoryFacade.createCbsClient(cbsClientConfiguration) + .flatMap(cbsClient -> cbsClient.get(CbsRequests.getAll(RequestDiagnosticContext.create()))) + .doOnError(e -> LOGGER.warn("Failed fetching config properties from CBS - retrying...", e)) + .retryBackoff(cbsProperties.getFetchRetries().getMaxAttempts(), + cbsProperties.getFetchRetries().getFirstBackoff(), + cbsProperties.getFetchRetries().getMaxBackoff()) + .doOnNext(this::updateCbsConfig) + .map(cbsJsonToPropertyMapConverter::convertToMap) + .block(); + return new MapPropertySource("cbs", properties); + } + + private void updateCbsConfig(JsonObject jsonObject) { + try { + cbsConfiguration.parseCBSConfig(jsonObject); + } catch (Exception e) { + LOGGER.error("Failed parsing configuration from CBS", e); + throw e; + } + } + +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/RetryProperties.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/RetryProperties.java new file mode 100644 index 00000000..44108a72 --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/RetryProperties.java @@ -0,0 +1,54 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2019 NOKIA 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.dcaegen2.services.bootstrap; + +import java.time.Duration; + +public class RetryProperties { + + private Integer maxAttempts = 10; + private Duration firstBackoff = Duration.ofSeconds(3); + private Duration maxBackoff = Duration.ofSeconds(15); + + public Integer getMaxAttempts() { + return maxAttempts; + } + + public void setMaxAttempts(Integer maxAttempts) { + this.maxAttempts = maxAttempts; + } + + public Duration getFirstBackoff() { + return firstBackoff; + } + + public void setFirstBackoff(Duration firstBackoff) { + this.firstBackoff = firstBackoff; + } + + public Duration getMaxBackoff() { + return maxBackoff; + } + + public void setMaxBackoff(Duration maxBackoff) { + this.maxBackoff = maxBackoff; + } +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/MainApp.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/MainApp.java index 3445c076..84d9fcd2 100644 --- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/MainApp.java +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/MainApp.java @@ -28,6 +28,7 @@ import org.slf4j.MDC; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.TaskScheduler; @@ -42,6 +43,7 @@ import static org.onap.dcaegen2.services.sdk.rest.services.model.logging.MdcVari @SpringBootApplication(exclude = {JacksonAutoConfiguration.class}) @Configuration @EnableScheduling +@EnableConfigurationProperties public class MainApp { public static void main(String[] args) { diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsClientConfigFileReader.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsClientConfigFileReader.java deleted file mode 100644 index f481f4ca..00000000 --- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsClientConfigFileReader.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * PNF-REGISTRATION-HANDLER - * ================================================================================ - * Copyright (C) 2018 NOKIA 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.dcaegen2.services.prh.configuration; - -import com.google.gson.Gson; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; - -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.CbsClientConfiguration; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.ImmutableCbsClientConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.io.Resource; -import org.springframework.stereotype.Component; -import reactor.core.publisher.Mono; - -@Component -public class CbsClientConfigFileReader { - - private static final Logger LOGGER = LoggerFactory.getLogger(CbsClientConfigFileReader.class); - - private final Resource cbsClientConfigFile; - - public CbsClientConfigFileReader(@Value("classpath:cbs_client_config.json") Resource cbsClientConfigFile) { - this.cbsClientConfigFile = cbsClientConfigFile; - } - - public Mono readConfig() { - LOGGER.debug("Loading CBS client configuration from configuration file"); - try (InputStream inputStream = cbsClientConfigFile.getInputStream()) { - CbsClientConfiguration config = new Gson().fromJson( - new InputStreamReader(inputStream, StandardCharsets.UTF_8), ImmutableCbsClientConfiguration.class); - LOGGER.info("Evaluated variables: {}", config); - return Mono.just(config); - } catch (Exception e) { - return Mono.error(new RuntimeException("Failed to load/parse CBS client configuration file", e)); - } - } - -} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsClientConfigurationResolver.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsClientConfigurationResolver.java deleted file mode 100644 index ce4cd4ed..00000000 --- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsClientConfigurationResolver.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * PNF-REGISTRATION-HANDLER - * ================================================================================ - * Copyright (C) 2019 NOKIA 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.dcaegen2.services.prh.configuration; - -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.CbsClientConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; -import reactor.core.publisher.Mono; - -@Component -public class CbsClientConfigurationResolver { - - private static final Logger LOGGER = LoggerFactory.getLogger(CbsClientConfigurationResolver.class); - private final CbsClientConfigFileReader cbsClientConfigFileReader; - - public CbsClientConfigurationResolver(CbsClientConfigFileReader cbsClientConfigFileReader) { - this.cbsClientConfigFileReader = cbsClientConfigFileReader; - } - - Mono resolveCbsClientConfiguration() { - return Mono.fromSupplier(CbsClientConfiguration::fromEnvironment) - .doOnError(err -> LOGGER.warn("Failed resolving CBS client configuration from system environments", err)) - .onErrorResume(err -> cbsClientConfigFileReader.readConfig()); - } - -} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsConfigRefreshScheduler.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsConfigRefreshScheduler.java new file mode 100644 index 00000000..fc4b9dff --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsConfigRefreshScheduler.java @@ -0,0 +1,97 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2019 NOKIA 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.dcaegen2.services.prh.configuration; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.context.environment.EnvironmentChangeEvent; +import org.springframework.cloud.context.refresh.ContextRefresher; +import org.springframework.context.event.EventListener; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; +import reactor.core.Disposable; +import reactor.core.publisher.Flux; +import reactor.core.scheduler.Scheduler; +import reactor.core.scheduler.Schedulers; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import java.time.Duration; + +@Component +public class CbsConfigRefreshScheduler { + + private static final Logger LOGGER = LoggerFactory.getLogger(CbsConfigRefreshScheduler.class); + private static final String CBS_UPDATES_INTERVAL_PROPERTY = "cbs.updates-interval"; + private static final Duration NO_UPDATES = Duration.ZERO; + + private final ContextRefresher contextRefresher; + private final Environment environment; + private final Scheduler scheduler; + private transient Disposable refreshEventsStreamHandle; + + + public CbsConfigRefreshScheduler(ContextRefresher contextRefresher, Environment environment) { + this.contextRefresher = contextRefresher; + this.environment = environment; + this.scheduler = Schedulers.newElastic("conf-updates"); + } + + @PostConstruct + public void startPollingForCbsUpdates() { + startPollingForCbsUpdates(getCbsUpdatesInterval()); + } + + private void startPollingForCbsUpdates(Duration updatesInterval) { + if (!updatesInterval.equals(NO_UPDATES)) { + LOGGER.info("Configuring pulling for CBS updates in every {}", updatesInterval); + refreshEventsStreamHandle = Flux.interval(updatesInterval, scheduler) + .doOnNext(i -> { + LOGGER.debug("Requesting context refresh"); + contextRefresher.refresh(); + }) + .onErrorContinue((e, o) -> LOGGER.error("Failed fetching config updates from CBS", e)) + .subscribe(); + } + } + + @EventListener + public void onEnvironmentChanged(EnvironmentChangeEvent event) { + if (event.getKeys().contains(CBS_UPDATES_INTERVAL_PROPERTY)) { + LOGGER.info("CBS config polling interval changed to {}", environment.getProperty(CBS_UPDATES_INTERVAL_PROPERTY)); + stopPollingForCbsUpdates(); + startPollingForCbsUpdates(getCbsUpdatesInterval()); + } + } + + private Duration getCbsUpdatesInterval() { + return environment.getProperty(CBS_UPDATES_INTERVAL_PROPERTY, Duration.class, NO_UPDATES); + } + + @PreDestroy + private void stopPollingForCbsUpdates() { + if(refreshEventsStreamHandle != null) { + LOGGER.debug("Stopping pulling for CBS updates"); + refreshEventsStreamHandle.dispose(); + } + } + +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsConfiguration.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsConfiguration.java index 1f752733..c1226359 100644 --- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsConfiguration.java +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsConfiguration.java @@ -22,24 +22,17 @@ package org.onap.dcaegen2.services.prh.configuration; import com.google.gson.JsonObject; import org.onap.dcaegen2.services.sdk.rest.services.aai.client.config.AaiClientConfiguration; -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.CbsClientConfiguration; import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.api.DmaapClientFactory; import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.api.MessageRouterPublisher; import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.api.MessageRouterSubscriber; import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRouterPublishRequest; import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRouterSubscribeRequest; -import org.onap.dcaegen2.services.sdk.rest.services.model.logging.RequestDiagnosticContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.context.annotation.Configuration; -import reactor.core.publisher.Flux; -import reactor.core.scheduler.Schedulers; import java.util.Optional; -@Configuration + public class CbsConfiguration implements Config { private static final Logger LOGGER = LoggerFactory.getLogger(CbsConfiguration.class); private static final String CBS_CONFIG_MISSING = "CBS config missing"; @@ -50,26 +43,8 @@ public class CbsConfiguration implements Config { private MessageRouterSubscribeRequest messageRouterCBSSubscribeRequest; private MessageRouterPublishRequest messageRouterCBSUpdatePublishRequest; - private final CbsClientConfigurationResolver cbsClientConfigurationResolver; - - public CbsConfiguration(CbsClientConfigurationResolver cbsClientConfigurationResolver) { - this.cbsClientConfigurationResolver = cbsClientConfigurationResolver; - } - - public void runTask() { - Flux.defer(cbsClientConfigurationResolver::resolveCbsClientConfiguration) - .subscribeOn(Schedulers.parallel()) - .subscribe(this::parsingConfigSuccess, this::parsingConfigError); - } - private void parsingConfigSuccess(CbsClientConfiguration cbsClientConfiguration) { - LOGGER.debug("Fetching PRH configuration from Consul"); - CbsClientFactory.createCbsClient(cbsClientConfiguration) - .flatMap(cbsClient -> cbsClient.get(CbsRequests.getAll(RequestDiagnosticContext.create()))) - .subscribe(this::parseCBSConfig, this::cbsConfigError); - } - - private void parseCBSConfig(JsonObject jsonObject) { + public void parseCBSConfig(JsonObject jsonObject) { LOGGER.info("Received application configuration: {}", jsonObject); CbsContentParser consulConfigurationParser = new CbsContentParser(jsonObject); @@ -85,14 +60,6 @@ public class CbsConfiguration implements Config { messageRouterCBSSubscribeRequest = consulConfigurationParser.getMessageRouterSubscribeRequest(); } - private void parsingConfigError(Throwable throwable) { - LOGGER.warn("Failed to process system environments", throwable); - } - - private void cbsConfigError(Throwable throwable) { - LOGGER.warn("Failed to gather configuration from ConfigBindingService/Consul", throwable); - } - @Override public MessageRouterPublisher getMessageRouterPublisher() { diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/PrhAppConfig.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/PrhAppConfig.java index 71d707bc..31794f6b 100644 --- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/PrhAppConfig.java +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/PrhAppConfig.java @@ -23,26 +23,28 @@ package org.onap.dcaegen2.services.prh.configuration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; +import org.springframework.boot.context.event.ApplicationStartedEvent; +import org.springframework.context.event.EventListener; import org.springframework.core.io.Resource; +import org.springframework.stereotype.Component; import org.springframework.util.StreamUtils; -import javax.annotation.PostConstruct; import java.io.IOException; import java.nio.charset.Charset; /** * @author Przemysław Wąsala on 4/9/18 */ -@Configuration +@Component public class PrhAppConfig { private static final Logger LOGGER = LoggerFactory.getLogger(PrhAppConfig.class); @Value("classpath:git_info.json") private Resource gitInfo; - @PostConstruct - private void printGitInfo() throws IOException { + + @EventListener + public void onApplicationStartedEvent(ApplicationStartedEvent applicationStartedEvent) throws IOException { if(LOGGER.isDebugEnabled()) { LOGGER.debug("Git info={}", StreamUtils.copyToString(gitInfo.getInputStream(), Charset.defaultCharset())); } @@ -51,4 +53,5 @@ public class PrhAppConfig { public Resource getGitInfo() { return gitInfo; } + } diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/ScheduledTasksRunner.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/ScheduledTasksRunner.java index bc13ddc4..c3eaa12f 100644 --- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/ScheduledTasksRunner.java +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/ScheduledTasksRunner.java @@ -21,18 +21,15 @@ package org.onap.dcaegen2.services.prh.tasks; import java.time.Duration; -import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ScheduledFuture; import javax.annotation.PostConstruct; -import org.onap.dcaegen2.services.prh.configuration.CbsConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.Marker; import org.slf4j.MarkerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.annotation.EnableScheduling; @@ -44,24 +41,17 @@ import org.springframework.scheduling.annotation.EnableScheduling; @Configuration @EnableScheduling public class ScheduledTasksRunner { - private static final int SCHEDULING_DELAY_FOR_PRH_TASKS = 10; - private static final int SCHEDULING_REQUEST_FOR_CONFIGURATION_DELAY = 5; private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledTasksRunner.class); private static final Marker ENTRY = MarkerFactory.getMarker("ENTRY"); private static volatile List scheduledPrhTaskFutureList = new ArrayList<>(); private final TaskScheduler taskScheduler; private final ScheduledTasks scheduledTask; - private final CbsConfiguration cbsConfiguration; - @Autowired - public ScheduledTasksRunner(TaskScheduler taskScheduler, - ScheduledTasks scheduledTask, - CbsConfiguration cbsConfiguration) { + public ScheduledTasksRunner(TaskScheduler taskScheduler, ScheduledTasks scheduledTask) { this.taskScheduler = taskScheduler; this.scheduledTask = scheduledTask; - this.cbsConfiguration = cbsConfiguration; } /** @@ -81,9 +71,6 @@ public class ScheduledTasksRunner { public synchronized boolean tryToStartTask() { LOGGER.info(ENTRY, "Start scheduling PRH workflow"); if (scheduledPrhTaskFutureList.isEmpty()) { - scheduledPrhTaskFutureList.add(taskScheduler - .scheduleAtFixedRate(cbsConfiguration::runTask, Instant.now(), - Duration.ofMinutes(SCHEDULING_REQUEST_FOR_CONFIGURATION_DELAY))); scheduledPrhTaskFutureList.add(taskScheduler .scheduleWithFixedDelay(scheduledTask::scheduleMainPrhEventTask, Duration.ofSeconds(SCHEDULING_DELAY_FOR_PRH_TASKS))); diff --git a/prh-app-server/src/main/resources/META-INF/spring.factories b/prh-app-server/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..78fde6e2 --- /dev/null +++ b/prh-app-server/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.cloud.bootstrap.BootstrapConfiguration=org.onap.dcaegen2.services.bootstrap.CbsBootstrapConfiguration \ No newline at end of file diff --git a/prh-app-server/src/main/resources/application.yaml b/prh-app-server/src/main/resources/application.yaml index 8139036c..2d244887 100644 --- a/prh-app-server/src/main/resources/application.yaml +++ b/prh-app-server/src/main/resources/application.yaml @@ -10,13 +10,16 @@ server: key-password: nokiapnf keyAlias: tomcat-localhost -management.endpoints.web.exposure.include: "loggers" - +management.endpoints.web.exposure.include: "loggers,refresh,env,health" --- spring: profiles: dev logging: level: - org.onap.dcaegen2.services.prh: info - org.onap.dcaegen2.services.sdk: info \ No newline at end of file + org.onap.dcaegen2.services.prh: debug + org.onap.dcaegen2.services.sdk: debug + +management.endpoints.web.exposure.include: "*" + + diff --git a/prh-app-server/src/main/resources/bootstrap.yaml b/prh-app-server/src/main/resources/bootstrap.yaml new file mode 100644 index 00000000..176c6bec --- /dev/null +++ b/prh-app-server/src/main/resources/bootstrap.yaml @@ -0,0 +1,23 @@ +spring: + application: + name: dcae-prh + + cloud: + config: + enabled: false + + +logging: + level: + org.springframework.boot.SpringApplication: warn + org.springframework.context.support.PostProcessorRegistrationDelegate: warn + +cbs: + hostname: cbs + port: 10000 + app-name: dcae-prh + updates-interval: 5m + fetch-retries: + max-attempts: 10 + first-backoff: 3s + max-backoff: 15s \ No newline at end of file diff --git a/prh-app-server/src/main/resources/cbs_client_config.json b/prh-app-server/src/main/resources/cbs_client_config.json deleted file mode 100644 index 0f196a1e..00000000 --- a/prh-app-server/src/main/resources/cbs_client_config.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "hostname": "cbs", - "port": 10000, - "appName": "dcae-prh" -} \ No newline at end of file diff --git a/prh-app-server/src/main/resources/logback-spring.xml b/prh-app-server/src/main/resources/logback-spring.xml index 03f4a103..060cf6c5 100644 --- a/prh-app-server/src/main/resources/logback-spring.xml +++ b/prh-app-server/src/main/resources/logback-spring.xml @@ -16,8 +16,6 @@ |%replace(%replace(%marker){'\t','\\\\t'}){'\n','\\\\n'} |%thread |%n"/> - - @@ -39,10 +37,7 @@ - - - - + -- cgit 1.2.3-korg