diff options
Diffstat (limited to 'prh-app-server')
48 files changed, 3165 insertions, 665 deletions
diff --git a/prh-app-server/pom.xml b/prh-app-server/pom.xml index e92515be..39249716 100644 --- a/prh-app-server/pom.xml +++ b/prh-app-server/pom.xml @@ -5,6 +5,7 @@ ~ ================================================================================ ~ Copyright (C) 2018-2022 NOKIA Intellectual Property. All rights reserved. ~ Copyright (C) 2021 Samsung Electronics. All rights reserved. + ~ Copyright (C) 2023 Deutsche Telekom 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. @@ -20,301 +21,329 @@ ~ ============LICENSE_END========================================================= --> <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> + 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> - <parent> - <groupId>org.onap.dcaegen2.services</groupId> - <artifactId>prh</artifactId> - <version>1.8.0-SNAPSHOT</version> - </parent> + <parent> + <groupId>org.onap.dcaegen2.services</groupId> + <artifactId>prh</artifactId> + <version>1.10.1-SNAPSHOT</version> + </parent> - <groupId>org.onap.dcaegen2.services.prh</groupId> - <artifactId>prh-app-server</artifactId> - <packaging>jar</packaging> + <groupId>org.onap.dcaegen2.services.prh</groupId> + <artifactId>prh-app-server</artifactId> + <packaging>jar</packaging> - <properties> - <maven.build.timestamp.format>yyyyMMdd'T'HHmmss</maven.build.timestamp.format> + <properties> + <maven.build.timestamp.format>yyyyMMdd'T'HHmmss</maven.build.timestamp.format> + <prh.main.class>org.onap.dcaegen2.services.prh.MainApp</prh.main.class> + <classpath.separator>@@</classpath.separator> + <dep.dir.name>libs</dep.dir.name> + <ext.dep.dir.path>${dep.dir.name}/external</ext.dep.dir.path> + <int.dep.dir.path>${dep.dir.name}/internal</int.dep.dir.path> + <skipDocker>false</skipDocker> + <docker.user.name>prh</docker.user.name> + <docker.user.dir>/home/${docker.user.name}</docker.user.dir> + <docker.user.id>1414</docker.user.id> + <onap-gerrit-review>-changelog-missing</onap-gerrit-review> + </properties> - <prh.main.class>org.onap.dcaegen2.services.prh.MainApp</prh.main.class> - <classpath.separator>@@</classpath.separator> - <dep.dir.name>libs</dep.dir.name> - <ext.dep.dir.path>${dep.dir.name}/external</ext.dep.dir.path> - <int.dep.dir.path>${dep.dir.name}/internal</int.dep.dir.path> + <build> + <resources> + <resource> + <directory>src/main/resources</directory> + </resource> + </resources> - <skipDocker>false</skipDocker> - <docker.user.name>prh</docker.user.name> - <docker.user.dir>/home/${docker.user.name}</docker.user.dir> - <docker.user.id>1414</docker.user.id> - </properties> + <plugins> + <plugin> + <groupId>pl.project13.maven</groupId> + <artifactId>git-commit-id-plugin</artifactId> + <configuration> + <dateFormat>${maven.build.timestamp.format}</dateFormat> + <generateGitPropertiesFile>true</generateGitPropertiesFile> + <format>json</format> + <generateGitPropertiesFilename> + ${project.build.outputDirectory}/git_info.json</generateGitPropertiesFilename> + </configuration> + <executions> + <execution> + <id>get-git-info</id> + <goals> + <goal>revision</goal> + </goals> + </execution> + </executions> + </plugin> - <build> - <resources> - <resource> - <directory>src/main/resources</directory> - </resource> - </resources> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <configuration> + <silent>true</silent> + <includeScope>runtime</includeScope> + <pathSeparator>${classpath.separator}</pathSeparator> + </configuration> + <executions> + <execution> + <id>copy-external-dependencies</id> + <phase>prepare-package</phase> + <goals> + <goal>copy-dependencies</goal> + <goal>build-classpath</goal> + </goals> + <configuration> + <excludeGroupIds>${project.parent.groupId}</excludeGroupIds> + <outputDirectory> + ${project.build.directory}/${ext.dep.dir.path}</outputDirectory> + <prefix>./${ext.dep.dir.path}</prefix> + <outputProperty>classpath.external</outputProperty> + </configuration> + </execution> + <execution> + <id>copy-internal-dependencies</id> + <phase>prepare-package</phase> + <goals> + <goal>copy-dependencies</goal> + <goal>build-classpath</goal> + </goals> + <configuration> + <includeGroupIds>${project.parent.groupId}</includeGroupIds> + <outputDirectory> + ${project.build.directory}/${int.dep.dir.path}</outputDirectory> + <prefix>./${int.dep.dir.path}</prefix> + <outputProperty>classpath.internal</outputProperty> + </configuration> + </execution> + </executions> + </plugin> - <plugins> - <plugin> - <groupId>pl.project13.maven</groupId> - <artifactId>git-commit-id-plugin</artifactId> - <configuration> - <dateFormat>${maven.build.timestamp.format}</dateFormat> - <generateGitPropertiesFile>true</generateGitPropertiesFile> - <format>json</format> - <generateGitPropertiesFilename>${project.build.outputDirectory}/git_info.json</generateGitPropertiesFilename> - </configuration> - <executions> - <execution> - <id>get-git-info</id> - <goals> - <goal>revision</goal> - </goals> - </execution> - </executions> - </plugin> + <plugin> <!-- workaround for MDEP-541 --> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>fix-classpath-separator</id> + <phase>prepare-package</phase> + <goals> + <goal>regex-properties</goal> + </goals> + <configuration> + <regexPropertySettings> + <regexPropertySetting> + <name>classpath.external</name> + <value>${classpath.external}</value> + <regex>${classpath.separator}</regex> + <replacement xml:space="preserve"> </replacement> + </regexPropertySetting> + <regexPropertySetting> + <name>classpath.internal</name> + <value>${classpath.internal}</value> + <regex>${classpath.separator}</regex> + <replacement xml:space="preserve"> </replacement> + </regexPropertySetting> + </regexPropertySettings> + </configuration> + </execution> + </executions> + </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-dependency-plugin</artifactId> - <configuration> - <silent>true</silent> - <includeScope>runtime</includeScope> - <pathSeparator>${classpath.separator}</pathSeparator> - </configuration> - <executions> - <execution> - <id>copy-external-dependencies</id> - <phase>prepare-package</phase> - <goals> - <goal>copy-dependencies</goal> - <goal>build-classpath</goal> - </goals> - <configuration> - <excludeGroupIds>${project.parent.groupId}</excludeGroupIds> - <outputDirectory>${project.build.directory}/${ext.dep.dir.path}</outputDirectory> - <prefix>./${ext.dep.dir.path}</prefix> - <outputProperty>classpath.external</outputProperty> - </configuration> - </execution> - <execution> - <id>copy-internal-dependencies</id> - <phase>prepare-package</phase> - <goals> - <goal>copy-dependencies</goal> - <goal>build-classpath</goal> - </goals> - <configuration> - <includeGroupIds>${project.parent.groupId}</includeGroupIds> - <outputDirectory>${project.build.directory}/${int.dep.dir.path}</outputDirectory> - <prefix>./${int.dep.dir.path}</prefix> - <outputProperty>classpath.internal</outputProperty> - </configuration> - </execution> - </executions> - </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifest> + <mainClass>${prh.main.class}</mainClass> + <addDefaultImplementationEntries>true</addDefaultImplementationEntries> + <addBuildEnvironmentEntries>true</addBuildEnvironmentEntries> + <useUniqueVersions>false</useUniqueVersions> <!-- + workaround for MJAR-156 --> + </manifest> + <manifestEntries> + <Class-Path>${classpath.external} + ${classpath.internal}</Class-Path> + <Git-Branch>${git.branch}</Git-Branch> + <Git-Build-Host>${git.build.host}</Git-Build-Host> + <Git-Build-Time>${git.build.time}</Git-Build-Time> + <Git-Build-User-Email>${git.build.user.email}</Git-Build-User-Email> + <Git-Build-User-Name>${git.build.user.name}</Git-Build-User-Name> + <Git-Build-Version>${git.build.version}</Git-Build-Version> + <Git-Closest-Tag-Name>${git.closest.tag.name}</Git-Closest-Tag-Name> + <Git-Commit-Id>${git.commit.id}</Git-Commit-Id> + <Git-Commit-Message-Short> + ${git.commit.message.short}</Git-Commit-Message-Short> + <Git-Commit-Time>${git.commit.time}</Git-Commit-Time> + <Git-Commit-User-Email>${git.commit.user.email}</Git-Commit-User-Email> + <Git-Commit-User-Name>${git.commit.user.name}</Git-Commit-User-Name> + </manifestEntries> + </archive> + </configuration> + </plugin> - <plugin> <!-- workaround for MDEP-541 --> - <groupId>org.codehaus.mojo</groupId> - <artifactId>build-helper-maven-plugin</artifactId> - <executions> - <execution> - <id>fix-classpath-separator</id> - <phase>prepare-package</phase> - <goals> - <goal>regex-properties</goal> - </goals> - <configuration> - <regexPropertySettings> - <regexPropertySetting> - <name>classpath.external</name> - <value>${classpath.external}</value> - <regex>${classpath.separator}</regex> - <replacement xml:space="preserve"> </replacement> - </regexPropertySetting> - <regexPropertySetting> - <name>classpath.internal</name> - <value>${classpath.internal}</value> - <regex>${classpath.separator}</regex> - <replacement xml:space="preserve"> </replacement> - </regexPropertySetting> - </regexPropertySettings> - </configuration> - </execution> - </executions> - </plugin> + <plugin> + <groupId>io.fabric8</groupId> + <artifactId>docker-maven-plugin</artifactId> + <configuration> + <verbose>true</verbose> + <imagePullPolicy>IfNotPresent</imagePullPolicy> + <images> + <image> + <name>onap/${project.groupId}.${project.artifactId}</name> + <registry>${onap.nexus.dockerregistry.daily}</registry> + <build> + <contextDir>${project.basedir}</contextDir> + <cleanup>none</cleanup> + <tags> + <tag>latest</tag> + <tag>${project.version}</tag> + <tag> + ${project.version}-${maven.build.timestamp}Z</tag> + </tags> + </build> + </image> + </images> + </configuration> + </plugin> + </plugins> + </build> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-jar-plugin</artifactId> - <configuration> - <archive> - <manifest> - <mainClass>${prh.main.class}</mainClass> - <addDefaultImplementationEntries>true</addDefaultImplementationEntries> - <addBuildEnvironmentEntries>true</addBuildEnvironmentEntries> - <useUniqueVersions>false</useUniqueVersions> <!-- workaround for MJAR-156 --> - </manifest> - <manifestEntries> - <Class-Path>${classpath.external} ${classpath.internal}</Class-Path> - <Git-Branch>${git.branch}</Git-Branch> - <Git-Build-Host>${git.build.host}</Git-Build-Host> - <Git-Build-Time>${git.build.time}</Git-Build-Time> - <Git-Build-User-Email>${git.build.user.email}</Git-Build-User-Email> - <Git-Build-User-Name>${git.build.user.name}</Git-Build-User-Name> - <Git-Build-Version>${git.build.version}</Git-Build-Version> - <Git-Closest-Tag-Name>${git.closest.tag.name}</Git-Closest-Tag-Name> - <Git-Commit-Id>${git.commit.id}</Git-Commit-Id> - <Git-Commit-Message-Short>${git.commit.message.short}</Git-Commit-Message-Short> - <Git-Commit-Time>${git.commit.time}</Git-Commit-Time> - <Git-Commit-User-Email>${git.commit.user.email}</Git-Commit-User-Email> - <Git-Commit-User-Name>${git.commit.user.name}</Git-Commit-User-Name> - </manifestEntries> - </archive> - </configuration> - </plugin> + <dependencies> + <dependency> + <groupId>org.onap.dcaegen2.services.prh</groupId> + <artifactId>prh-commons</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.dcaegen2.services.sdk.rest.services</groupId> + <artifactId>cbs-client</artifactId> + <!--<version>1.9.3-SNAPSHOT</version>--> + </dependency> + <dependency> + <groupId>org.onap.dcaegen2.services.sdk.rest.services</groupId> + <artifactId>dmaap-client</artifactId> + </dependency> - <plugin> - <groupId>io.fabric8</groupId> - <artifactId>docker-maven-plugin</artifactId> - <configuration> - <verbose>true</verbose> - <imagePullPolicy>IfNotPresent</imagePullPolicy> - <images> - <image> - <name>onap/${project.groupId}.${project.artifactId}</name> - <registry>${onap.nexus.dockerregistry.daily}</registry> - <build> - <contextDir>${project.basedir}</contextDir> - <cleanup>none</cleanup> - <tags> - <tag>latest</tag> - <tag>${project.version}</tag> - <tag>${project.version}-${maven.build.timestamp}Z</tag> - </tags> - </build> - </image> - </images> - </configuration> - </plugin> - </plugins> - </build> + <dependency> + <groupId>org.springframework.cloud</groupId> + <artifactId>spring-cloud-starter-config</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.cloud</groupId> + <artifactId>spring-cloud-starter-bootstrap</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-webflux</artifactId> + </dependency> + <dependency> + <groupId>org.springdoc</groupId> + <artifactId>springdoc-openapi-ui</artifactId> + </dependency> + <dependency> + <groupId>io.projectreactor</groupId> + <artifactId>reactor-core</artifactId> + </dependency> + <dependency> + <groupId>org.apache.tomcat.embed</groupId> + <artifactId>tomcat-embed-core</artifactId> + </dependency> + <dependency> + <groupId>org.apache.tomcat.embed</groupId> + <artifactId>tomcat-embed-el</artifactId> + </dependency> + <dependency> + <groupId>org.apache.tomcat.embed</groupId> + <artifactId>tomcat-embed-websocket</artifactId> + </dependency> - <dependencies> - <dependency> - <groupId>org.onap.dcaegen2.services.prh</groupId> - <artifactId>prh-commons</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.onap.dcaegen2.services.sdk.rest.services</groupId> - <artifactId>cbs-client</artifactId> - </dependency> - <dependency> - <groupId>org.onap.dcaegen2.services.sdk.rest.services</groupId> - <artifactId>dmaap-client</artifactId> - </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-configuration-processor</artifactId> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-actuator</artifactId> + </dependency> - <dependency> - <groupId>org.springframework.cloud</groupId> - <artifactId>spring-cloud-starter-config</artifactId> - </dependency> - <dependency> - <groupId>org.springframework.cloud</groupId> - <artifactId>spring-cloud-starter-bootstrap</artifactId> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-web</artifactId> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-webflux</artifactId> - </dependency> - <dependency> - <groupId>io.springfox</groupId> - <artifactId>springfox-boot-starter</artifactId> - </dependency> - <dependency> - <groupId>io.projectreactor</groupId> - <artifactId>reactor-core</artifactId> - </dependency> - <dependency> - <groupId>org.apache.tomcat.embed</groupId> - <artifactId>tomcat-embed-core</artifactId> - </dependency> - <dependency> - <groupId>org.apache.tomcat.embed</groupId> - <artifactId>tomcat-embed-el</artifactId> - </dependency> - <dependency> - <groupId>org.apache.tomcat.embed</groupId> - <artifactId>tomcat-embed-websocket</artifactId> - </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-configuration-processor</artifactId> - <optional>true</optional> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-actuator</artifactId> - </dependency> - - <dependency> - <groupId>com.google.guava</groupId> - <artifactId>guava</artifactId> - </dependency> - - <dependency> - <groupId>org.junit.jupiter</groupId> - <artifactId>junit-jupiter-engine</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.mockito</groupId> - <artifactId>mockito-junit-jupiter</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.assertj</groupId> - <artifactId>assertj-core</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-test</artifactId> - <scope>test</scope> - <exclusions> - <exclusion> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>org.springframework.cloud</groupId> - <artifactId>spring-cloud-contract-wiremock</artifactId> - <scope>test</scope> - <exclusions> - <exclusion> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>io.projectreactor</groupId> - <artifactId>reactor-test</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.glassfish.jersey.connectors</groupId> - <artifactId>jersey-apache-connector</artifactId> - <scope>test</scope> - </dependency> - </dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-junit-jupiter</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.springframework.cloud</groupId> + <artifactId>spring-cloud-contract-wiremock</artifactId> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>io.projectreactor</groupId> + <artifactId>reactor-test</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.glassfish.jersey.connectors</groupId> + <artifactId>jersey-apache-connector</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework.kafka</groupId> + <artifactId>spring-kafka</artifactId> + <version>2.8.11</version> + </dependency> + <dependency> + <groupId>com.github.stefanbirkner</groupId> + <artifactId>system-lambda</artifactId> + <version>1.2.1</version> + </dependency> + <dependency> + <groupId>com.github.stefanbirkner</groupId> + <artifactId>system-rules</artifactId> + <version>1.19.0</version> + </dependency> + <dependency> + <groupId>uk.org.webcompere</groupId> + <artifactId>system-stubs-jupiter</artifactId> + <version>1.1.0</version> + <scope>test</scope> + </dependency> + </dependencies> </project> 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 index f668a581..c82c326f 100644 --- 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 @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -22,26 +23,36 @@ package org.onap.dcaegen2.services.bootstrap; import org.onap.dcaegen2.services.prh.configuration.CbsConfiguration; +import org.onap.dcaegen2.services.prh.configuration.CbsConfigurationForAutoCommitDisabledMode; 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; +import org.springframework.context.annotation.Profile; + @Configuration @EnableConfigurationProperties(CbsProperties.class) public class CbsBootstrapConfiguration { - private static final CbsConfiguration CBS_CONFIGURATION = new CbsConfiguration(); + + private static CbsConfiguration CBS_CONFIGURATION = new CbsConfiguration(); + private static CbsConfigurationForAutoCommitDisabledMode CBS_CONFIGURATION_FOR_AUTO_COMMIT_DISABLED_MODE = + new CbsConfigurationForAutoCommitDisabledMode(); @Bean - public CbsProperties cbsProperties() { + public CbsProperties cbsProperties() + { return new CbsProperties(); } @Bean @ConditionalOnProperty(value = "cbs.enabled", matchIfMissing = true) + @Profile("!autoCommitDisabled") public CbsPropertySourceLocator cbsPropertySourceLocator( CbsProperties cbsProperties, CbsConfiguration cbsConfiguration) { + + System.out.println("Trying to return CbsPropertySourceLocator bean"); return new CbsPropertySourceLocator( cbsProperties, @@ -50,9 +61,33 @@ public class CbsBootstrapConfiguration { new CbsClientFactoryFacade(), cbsConfiguration); } + + @Bean + @ConditionalOnProperty(value = "cbs.enabled", matchIfMissing = true) + @Profile("autoCommitDisabled") + public CbsPropertySourceLocatorForAutoCommitDisabled cbsPropertySourceLocatorForAutoCommitDisabled(CbsProperties cbsProperties, + CbsConfigurationForAutoCommitDisabledMode cbsConfigurationforAutoCommitdisabledMode) { + + System.out.println("Trying to return CbsPropertySourceLocatorForAutoCommitDisabled bean"); + + CbsPropertySourceLocatorForAutoCommitDisabled cbsPropertySourceLocatorACDM = new CbsPropertySourceLocatorForAutoCommitDisabled(cbsProperties, + new CbsJsonToPropertyMapConverter(), new CbsClientConfigurationResolver(cbsProperties), + new CbsClientFactoryFacade(), cbsConfigurationforAutoCommitdisabledMode); + + return cbsPropertySourceLocatorACDM; + + } @Bean + @Profile("!autoCommitDisabled") public CbsConfiguration cbsConfiguration() { - return CBS_CONFIGURATION; + return CBS_CONFIGURATION; + } + + @Bean + @Profile("autoCommitDisabled") + public CbsConfigurationForAutoCommitDisabledMode cbsConfigurationForAutoCommitDisabledMode() { + return CBS_CONFIGURATION_FOR_AUTO_COMMIT_DISABLED_MODE; } + } 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 index 18d4021b..5fa4cdbe 100644 --- 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 @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -35,34 +36,14 @@ public class CbsProperties { 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; } 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 index 2b5ac2e5..b4875eed 100644 --- 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 @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2019-2021 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -28,6 +29,7 @@ import org.onap.dcaegen2.services.sdk.rest.services.model.logging.RequestDiagnos import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.bootstrap.config.PropertySourceLocator; +import org.springframework.context.annotation.Profile; import org.springframework.core.env.Environment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; @@ -35,6 +37,7 @@ import reactor.util.retry.Retry; import java.util.Map; +@Profile("!autoCommitDisabled") public class CbsPropertySourceLocator implements PropertySourceLocator { private static final Logger LOGGER = LoggerFactory.getLogger(CbsPropertySourceLocator.class); @@ -43,37 +46,40 @@ public class CbsPropertySourceLocator implements PropertySourceLocator { 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; + 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(); Map<String, Object> properties = cbsClientFactoryFacade.createCbsClient(cbsClientConfiguration) .flatMap(cbsClient -> cbsClient.get(CbsRequests.getAll(RequestDiagnosticContext.create()))) .doOnError(e -> LOGGER.warn("Failed loading configuration - retrying...", e)) - .retryWhen(Retry. - backoff(cbsProperties.getFetchRetries().getMaxAttempts(), cbsProperties.getFetchRetries().getFirstBackoff()). - maxBackoff(cbsProperties.getFetchRetries().getMaxBackoff())) - .doOnNext(this::updateCbsConfig) - .map(cbsJsonToPropertyMapConverter::convertToMap) - .block(); + .retryWhen(Retry + .backoff(cbsProperties.getFetchRetries().getMaxAttempts(), + cbsProperties.getFetchRetries().getFirstBackoff()) + .maxBackoff(cbsProperties.getFetchRetries().getMaxBackoff())) + .doOnNext(this::updateCbsConfig).map(cbsJsonToPropertyMapConverter::convertToMap).block(); + return new MapPropertySource("cbs", properties); } private void updateCbsConfig(JsonObject jsonObject) { try { + LOGGER.info("Updating CBS configuration"); cbsConfiguration.parseCBSConfig(jsonObject); + } catch (Exception e) { LOGGER.error("Failed parsing configuration", e); throw e; diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsPropertySourceLocatorForAutoCommitDisabled.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsPropertySourceLocatorForAutoCommitDisabled.java new file mode 100644 index 00000000..b7aa1f58 --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/bootstrap/CbsPropertySourceLocatorForAutoCommitDisabled.java @@ -0,0 +1,94 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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.CbsConfigurationForAutoCommitDisabledMode; +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.context.annotation.Profile; +import org.springframework.core.env.Environment; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.PropertySource; +import reactor.util.retry.Retry; +import java.util.Map; + +/** + * * @author <a href="mailto:PRANIT.KAPDULE@t-systems.com">Pranit Kapdule</a> on + * * 24/08/23 + * */ + +@Profile("autoCommitDisabled") +public class CbsPropertySourceLocatorForAutoCommitDisabled implements PropertySourceLocator { + private static final Logger LOGGER = LoggerFactory.getLogger(CbsPropertySourceLocatorForAutoCommitDisabled.class); + + private final CbsProperties cbsProperties; + private final CbsJsonToPropertyMapConverter cbsJsonToPropertyMapConverter; + private final CbsClientConfigurationResolver cbsClientConfigurationResolver; + private final CbsClientFactoryFacade cbsClientFactoryFacade; + private final CbsConfigurationForAutoCommitDisabledMode cbsConfigurationForAutoCommitDisabledMode; + + public CbsPropertySourceLocatorForAutoCommitDisabled(CbsProperties cbsProperties, + CbsJsonToPropertyMapConverter cbsJsonToPropertyMapConverter, + CbsClientConfigurationResolver cbsClientConfigurationResolver, + CbsClientFactoryFacade cbsClientFactoryFacade, CbsConfigurationForAutoCommitDisabledMode cbsConfigurationForAutoCommitDisabledMode) { + + this.cbsProperties = cbsProperties; + this.cbsJsonToPropertyMapConverter = cbsJsonToPropertyMapConverter; + this.cbsClientConfigurationResolver = cbsClientConfigurationResolver; + this.cbsClientFactoryFacade = cbsClientFactoryFacade; + this.cbsConfigurationForAutoCommitDisabledMode = cbsConfigurationForAutoCommitDisabledMode; + + } + + @Override + public PropertySource<?> locate(Environment environment) { + + CbsClientConfiguration cbsClientConfiguration = cbsClientConfigurationResolver.resolveCbsClientConfiguration(); + Map<String, Object> properties = cbsClientFactoryFacade.createCbsClient(cbsClientConfiguration) + .flatMap(cbsClient -> cbsClient.get(CbsRequests.getAll(RequestDiagnosticContext.create()))) + .doOnError(e -> LOGGER.warn("Failed loading configuration - retrying...", e)) + .retryWhen(Retry + .backoff(cbsProperties.getFetchRetries().getMaxAttempts(), + cbsProperties.getFetchRetries().getFirstBackoff()) + .maxBackoff(cbsProperties.getFetchRetries().getMaxBackoff())) + .doOnNext(this::updateCbsConfig) + .map(cbsJsonToPropertyMapConverter::convertToMap).block(); + + return new MapPropertySource("cbs", properties); + } + + private void updateCbsConfig(JsonObject jsonObject) { + try { + LOGGER.info("Updating CBS configuration"); + cbsConfigurationForAutoCommitDisabledMode.parseCBSConfig(jsonObject); + + } catch (Exception e) { + LOGGER.error("Failed parsing configuration", e); + throw e; + } + } + +} 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 1d2a65d3..5a986517 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 @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2018 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -22,7 +23,6 @@ package org.onap.dcaegen2.services.prh; import java.util.Map; import java.util.UUID; - import org.slf4j.MDC; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -32,19 +32,22 @@ import org.springframework.context.annotation.Bean; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler; - import static org.onap.dcaegen2.services.sdk.rest.services.model.logging.MdcVariables.INVOCATION_ID; /** - * @author <a href="mailto:przemyslaw.wasala@nokia.com">Przemysław Wąsala</a> on 3/23/18 + * @author <a href="mailto:przemyslaw.wasala@nokia.com">Przemysław Wąsala</a> on + * 3/23/18 */ -@SpringBootApplication(exclude = {JacksonAutoConfiguration.class}) +@SpringBootApplication(exclude = { JacksonAutoConfiguration.class }) @EnableScheduling @EnableConfigurationProperties public class MainApp { + public static void main(String[] args) { + SpringApplication.run(MainApp.class, args); + } @Bean diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/AaiHttpClientConfig.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/AaiHttpClientConfig.java index 39369329..cd0d8d2a 100644 --- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/AaiHttpClientConfig.java +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/AaiHttpClientConfig.java @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2018 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -21,6 +22,7 @@ package org.onap.dcaegen2.services.prh.configuration; import java.nio.charset.StandardCharsets; + import java.util.function.BiFunction; import org.onap.dcaegen2.services.prh.adapter.aai.api.AaiHttpClient; import org.onap.dcaegen2.services.prh.adapter.aai.api.AaiPnfResultModel; @@ -39,47 +41,48 @@ import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.RxHttpClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; @Configuration public class AaiHttpClientConfig { @Autowired - private CbsConfiguration cbsConfiguration; + private Config config; @Bean public AaiHttpClient<ConsumerDmaapModel, HttpResponse> getPatchClientFactory() { return createLazyConfigClient( - (config, client) -> new AaiHttpPatchClient(config, new AaiJsonBodyBuilderImpl(), client)); + (config, client) -> new AaiHttpPatchClient(config, new AaiJsonBodyBuilderImpl(), client)); } @Bean public AaiHttpClient<AaiServiceInstanceQueryModel, AaiServiceInstanceResultModel> getServiceInstanceClient() { return createLazyConfigClient( - (config, client) -> new AaiGetServiceInstanceClient(config, client) - .map(httpResponse -> { + (config, client) -> new AaiGetServiceInstanceClient(config, client).map(httpResponse -> { httpResponse.throwIfUnsuccessful(); - return httpResponse.bodyAsJson(StandardCharsets.UTF_8, - PrhModelAwareGsonBuilder.createGson(), AaiServiceInstanceResultModel.class); + return httpResponse.bodyAsJson(StandardCharsets.UTF_8, PrhModelAwareGsonBuilder.createGson(), + AaiServiceInstanceResultModel.class); })); } @Bean public AaiHttpClient<ConsumerDmaapModel, AaiPnfResultModel> getGetClient() { - return createLazyConfigClient( - (config, client) -> new AaiHttpGetClient(config, client) - .map(httpResponse -> { - httpResponse.throwIfUnsuccessful(); - return httpResponse.bodyAsJson(StandardCharsets.UTF_8, - PrhModelAwareGsonBuilder.createGson(), AaiPnfResultModel.class); - })); + + + + return createLazyConfigClient((config, client) -> new AaiHttpGetClient(config, client).map(httpResponse -> { + httpResponse.throwIfUnsuccessful(); + return httpResponse.bodyAsJson(StandardCharsets.UTF_8, PrhModelAwareGsonBuilder.createGson(), + AaiPnfResultModel.class); + })); } private <T, U> AaiHttpClient<T, U> createLazyConfigClient( - final BiFunction<AaiClientConfiguration, RxHttpClient, AaiHttpClient<T, U>> factoryMethod) { + final BiFunction<AaiClientConfiguration, RxHttpClient, AaiHttpClient<T, U>> factoryMethod) { +// System.out.println("pnf url in AAIClientConfiguration is: " + config.getAaiClientConfiguration().pnfUrl()); +// System.out.println("base url in AAIClientConfiguration is: " + config.getAaiClientConfiguration().baseUrl()); + return x -> factoryMethod.apply(config.getAaiClientConfiguration(), + new AaiHttpClientFactory(config.getAaiClientConfiguration()).build()).getAaiResponse(x); - return x -> factoryMethod.apply( - cbsConfiguration.getAaiClientConfiguration(), - new AaiHttpClientFactory(cbsConfiguration.getAaiClientConfiguration()).build() - ).getAaiResponse(x); } } 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 8373018d..22763e8b 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 @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2018 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -30,35 +31,42 @@ import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRo import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRouterSubscribeRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +@Profile("!autoCommitDisabled") public class CbsConfiguration implements Config { private static final Logger LOGGER = LoggerFactory.getLogger(CbsConfiguration.class); - private static final String CBS_CONFIG_MISSING = "CBS config missing"; - private AaiClientConfiguration aaiClientCBSConfiguration; - private MessageRouterPublisher messageRouterPublisher; - private MessageRouterSubscriber messageRouterSubscriber; - private MessageRouterPublishRequest messageRouterCBSPublishRequest; - private MessageRouterSubscribeRequest messageRouterCBSSubscribeRequest; - private MessageRouterPublishRequest messageRouterCBSUpdatePublishRequest; - - + protected static final String CBS_CONFIG_MISSING = "CBS config missing"; + protected AaiClientConfiguration aaiClientCBSConfiguration; + protected MessageRouterPublisher messageRouterPublisher; + protected MessageRouterSubscriber messageRouterSubscriber; + protected MessageRouterPublishRequest messageRouterCBSPublishRequest; + protected MessageRouterSubscribeRequest messageRouterCBSSubscribeRequest; + protected MessageRouterPublishRequest messageRouterCBSUpdatePublishRequest; + public void parseCBSConfig(JsonObject jsonObject) { + LOGGER.info("Received application configuration: {}", jsonObject); - CbsContentParser consulConfigurationParser = new CbsContentParser(jsonObject); - + CbsContentParser consulConfigurationParser = new CbsContentParser(jsonObject); aaiClientCBSConfiguration = consulConfigurationParser.getAaiClientConfig(); - messageRouterPublisher = DmaapClientFactory.createMessageRouterPublisher( - consulConfigurationParser.getMessageRouterPublisherConfig()); + messageRouterPublisher = DmaapClientFactory + .createMessageRouterPublisher(consulConfigurationParser.getMessageRouterPublisherConfig()); messageRouterCBSPublishRequest = consulConfigurationParser.getMessageRouterPublishRequest(); messageRouterCBSUpdatePublishRequest = consulConfigurationParser.getMessageRouterUpdatePublishRequest(); - messageRouterSubscriber = DmaapClientFactory.createMessageRouterSubscriber( - consulConfigurationParser.getMessageRouterSubscriberConfig()); + messageRouterSubscriber = DmaapClientFactory + .createMessageRouterSubscriber(consulConfigurationParser.getMessageRouterSubscriberConfig()); + String prevTopicUrl = null; + if(messageRouterCBSSubscribeRequest != null) { + prevTopicUrl = messageRouterCBSSubscribeRequest.sourceDefinition().topicUrl(); + } messageRouterCBSSubscribeRequest = consulConfigurationParser.getMessageRouterSubscribeRequest(); - } - + if(!messageRouterCBSSubscribeRequest.sourceDefinition().topicUrl().equals(prevTopicUrl)) { + messageRouterSubscriber.close(); + } + } @Override public MessageRouterPublisher getMessageRouterPublisher() { @@ -72,21 +80,26 @@ public class CbsConfiguration implements Config { @Override public MessageRouterPublishRequest getMessageRouterPublishRequest() { - return Optional.ofNullable(messageRouterCBSPublishRequest).orElseThrow(() -> new RuntimeException(CBS_CONFIG_MISSING)); + return Optional.ofNullable(messageRouterCBSPublishRequest) + .orElseThrow(() -> new RuntimeException(CBS_CONFIG_MISSING)); } @Override public MessageRouterPublishRequest getMessageRouterUpdatePublishRequest() { - return Optional.ofNullable(messageRouterCBSUpdatePublishRequest).orElseThrow(() -> new RuntimeException(CBS_CONFIG_MISSING)); + return Optional.ofNullable(messageRouterCBSUpdatePublishRequest) + .orElseThrow(() -> new RuntimeException(CBS_CONFIG_MISSING)); } @Override public AaiClientConfiguration getAaiClientConfiguration() { - return Optional.ofNullable(aaiClientCBSConfiguration).orElseThrow(() -> new RuntimeException(CBS_CONFIG_MISSING)); + return Optional.ofNullable(aaiClientCBSConfiguration) + .orElseThrow(() -> new RuntimeException(CBS_CONFIG_MISSING)); } @Override public MessageRouterSubscribeRequest getMessageRouterSubscribeRequest() { - return Optional.ofNullable(messageRouterCBSSubscribeRequest).orElseThrow(() -> new RuntimeException(CBS_CONFIG_MISSING)); + return Optional.ofNullable(messageRouterCBSSubscribeRequest) + .orElseThrow(() -> new RuntimeException(CBS_CONFIG_MISSING)); } + } diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsConfigurationForAutoCommitDisabledMode.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsConfigurationForAutoCommitDisabledMode.java new file mode 100644 index 00000000..b20cbad6 --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsConfigurationForAutoCommitDisabledMode.java @@ -0,0 +1,67 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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 java.util.Optional; +import org.onap.dcaegen2.services.prh.adapter.kafka.ImmutableKafkaConfiguration; +import org.onap.dcaegen2.services.prh.adapter.kafka.KafkaConfiguration; +import org.springframework.context.annotation.Profile; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +/** + * @author <a href="mailto:PRANIT.KAPDULE@t-systems.com">Pranit Kapdule</a> on + * 24/08/23 + */ +@Profile("autoCommitDisabled") +public class CbsConfigurationForAutoCommitDisabledMode extends CbsConfiguration { + + protected KafkaConfiguration kafkaConfiguration; + + @Override + public void parseCBSConfig(JsonObject jsonObject) { + + super.parseCBSConfig(jsonObject); + JsonObject jsonObjectforAutoCommitDisabled = jsonObject.getAsJsonObject("config"); + JsonElement jsonObjectOfKafkaConfigurations = jsonObjectforAutoCommitDisabled.get("kafka-configurations"); + + kafkaConfiguration = new ImmutableKafkaConfiguration.Builder() + .kafkaBoostrapServerConfig( + ((JsonObject) jsonObjectOfKafkaConfigurations).get("kafkaBoostrapServerConfig").getAsString()) + .groupIdConfig(((JsonObject) jsonObjectOfKafkaConfigurations).get("groupIdConfig").getAsString()) + .kafkaSaslMechanism( + ((JsonObject) jsonObjectOfKafkaConfigurations).get("kafkaSaslMechanism").getAsString()) + .kafkaSecurityProtocol( + ((JsonObject) jsonObjectOfKafkaConfigurations).get("kafkaSecurityProtocol").getAsString()) + .kafkaJaasConfig(System.getenv("JAAS_CONFIG")) + .build(); + + } + + public KafkaConfiguration getKafkaConfig() { + return Optional.ofNullable(kafkaConfiguration).orElseThrow(() -> new RuntimeException(CBS_CONFIG_MISSING)); + } + + public void setKafkaConfiguration(KafkaConfiguration kafkaConfiguration) { + this.kafkaConfiguration = kafkaConfiguration; + } + +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsContentParser.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsContentParser.java index ed935501..e1200119 100644 --- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsContentParser.java +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CbsContentParser.java @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2018 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -139,4 +140,4 @@ class CbsContentParser { .timeout(Duration.ofMillis(jsonObject.get("dmaap.dmaapConsumerConfiguration.timeoutMs").getAsLong())) .build(); } -}
\ No newline at end of file +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/KafkaConfig.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/KafkaConfig.java new file mode 100644 index 00000000..baaf3b16 --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/KafkaConfig.java @@ -0,0 +1,106 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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 java.util.HashMap; +import java.util.Map; +import org.springframework.context.annotation.Profile; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.annotation.EnableKafka; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.listener.ContainerProperties; + + /** + * * @author <a href="mailto:PRANIT.KAPDULE@t-systems.com">Pranit Kapdule</a> on + * * 24/08/23 + * */ + +@Profile("autoCommitDisabled") +@EnableKafka +@Configuration +public class KafkaConfig { + + CbsConfigurationForAutoCommitDisabledMode cbsConfigurationForAutoCommitDisabledMode; + + public String kafkaBoostrapServerConfig; + public String groupIdConfig; + public String kafkaSecurityProtocol; + public String kafkaSaslMechanism; + public String kafkaUsername; + public String kafkaPassword; + public String kafkaJaasConfigName; + public String kafkaLoginModuleClassConfig; + public String kafkaJaasConfig; + + public final String DEFAULT_KAFKA_SECURITY_PROTOCOL = "SASL_PLAINTEXT"; + public final String DEFAULT_KAFKA_SASL_MECHANISM = "SCRAM-SHA-512"; + + public KafkaConfig() { + + } + + @Bean + public ConsumerFactory<String, String> consumerFactory(CbsConfigurationForAutoCommitDisabledMode cbsConfigurationForAutoCommitDisabledMode) { + this.cbsConfigurationForAutoCommitDisabledMode = cbsConfigurationForAutoCommitDisabledMode; + kafkaBoostrapServerConfig = cbsConfigurationForAutoCommitDisabledMode.getKafkaConfig() + .kafkaBoostrapServerConfig(); + groupIdConfig = cbsConfigurationForAutoCommitDisabledMode.getKafkaConfig().groupIdConfig(); + kafkaSecurityProtocol = cbsConfigurationForAutoCommitDisabledMode.getKafkaConfig().kafkaSecurityProtocol(); + kafkaSaslMechanism = cbsConfigurationForAutoCommitDisabledMode.getKafkaConfig().kafkaSaslMechanism(); + kafkaJaasConfig = cbsConfigurationForAutoCommitDisabledMode.getKafkaConfig().kafkaJaasConfig(); + + Map<String, Object> config = new HashMap<>(); + config.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaBoostrapServerConfig); + + config.put(ConsumerConfig.GROUP_ID_CONFIG, groupIdConfig); + config.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, + "org.apache.kafka.common.serialization.StringDeserializer"); + config.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, + "org.apache.kafka.common.serialization.StringDeserializer"); + config.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false); + + if (kafkaSecurityProtocol == null) + kafkaSecurityProtocol = DEFAULT_KAFKA_SECURITY_PROTOCOL; + config.put("security.protocol", kafkaSecurityProtocol); + if (kafkaSaslMechanism == null) + kafkaSaslMechanism = DEFAULT_KAFKA_SASL_MECHANISM; + config.put("sasl.mechanism", kafkaSaslMechanism); + + config.put("sasl.jaas.config", kafkaJaasConfig); + + return new DefaultKafkaConsumerFactory<>(config); + + } + + @Bean + public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory( + CbsConfigurationForAutoCommitDisabledMode cbsConfigurationForAutoCommitDisabledMode) { + ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(consumerFactory(cbsConfigurationForAutoCommitDisabledMode)); + factory.setBatchListener(true); + factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL); + return factory; + } + +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/SwaggerConfig.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/SwaggerConfig.java deleted file mode 100644 index 4039f698..00000000 --- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/SwaggerConfig.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * PNF-REGISTRATION-HANDLER - * ================================================================================ - * Copyright (C) 2018-2020 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.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - - -@Configuration -@Profile("prod") -public class SwaggerConfig extends WebMvcConfigurationSupport { - - private static final String PACKAGE_PATH = "org.onap.dcaegen2.services.prh"; - private static final String API_TITLE = "PRH app server"; - private static final String DESCRIPTION = "This page lists all the rest apis for PRH app server."; - private static final String VERSION = "1.0"; - private static final String RESOURCES_PATH = "classpath:/META-INF/resources/"; - private static final String WEBJARS_PATH = RESOURCES_PATH + "webjars/"; - private static final String SWAGGER_UI = "swagger-ui.html"; - private static final String WEBJARS = "/webjars/**"; - - /** - * Swagger configuration function for hosting it next to spring http website. - * - * @return Docket - */ - @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2) - .apiInfo(apiInfo()) - .select() - .apis(RequestHandlerSelectors.basePackage(PACKAGE_PATH)) - .paths(PathSelectors.any()) - .build(); - } - - private ApiInfo apiInfo() { - return new ApiInfoBuilder() - .title(API_TITLE) - .description(DESCRIPTION) - .version(VERSION) - .build(); - } - - - @Override - protected void addResourceHandlers(ResourceHandlerRegistry registry) { - registry.addResourceHandler(SWAGGER_UI) - .addResourceLocations(RESOURCES_PATH); - - registry.addResourceHandler(WEBJARS) - .addResourceLocations(WEBJARS_PATH); - } -} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/controllers/ScheduleController.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/controllers/ScheduleController.java index a0aa17e3..aafcd81a 100644 --- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/controllers/ScheduleController.java +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/controllers/ScheduleController.java @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2018 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -26,6 +27,7 @@ import org.onap.dcaegen2.services.prh.tasks.ScheduledTasksRunner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; @@ -34,17 +36,19 @@ import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Mono; /** - * @author <a href="mailto:przemyslaw.wasala@nokia.com">Przemysław Wąsala</a> on 4/5/18 + * @author <a href="mailto:przemyslaw.wasala@nokia.com">Przemysław Wąsala</a> on + * 4/5/18 */ @RestController -@Api(value = "ScheduleController", description = "Schedule Controller") +@Api(value = "ScheduleController") +@Profile("!autoCommitDisabled") public class ScheduleController { private static final Logger LOGGER = LoggerFactory.getLogger(ScheduleController.class); + private ScheduledTasksRunner scheduledTasksRunner; - private final ScheduledTasksRunner scheduledTasksRunner; - @Autowired + @Autowired(required = false) public ScheduleController(ScheduledTasksRunner scheduledTasksRunner) { this.scheduledTasksRunner = scheduledTasksRunner; } @@ -52,7 +56,7 @@ public class ScheduleController { @RequestMapping(value = "start", method = RequestMethod.GET) @ApiOperation(value = "Start scheduling worker request") public Mono<ResponseEntity<String>> startTasks() { - LOGGER.trace("Receiving start scheduling worker request"); + LOGGER.trace("Receiving start scheduling worker request with Comit SchedulerController"); return Mono.fromSupplier(scheduledTasksRunner::tryToStartTask).map(this::createStartTaskResponse); } @@ -61,10 +65,10 @@ public class ScheduleController { public Mono<ResponseEntity<String>> stopTask() { LOGGER.trace("Receiving stop scheduling worker request"); return Mono.defer(() -> { - scheduledTasksRunner.cancelTasks(); - return Mono.just(new ResponseEntity<>("PRH Service has been stopped!", HttpStatus.OK)); - } - ); + scheduledTasksRunner.closeKafkaPublisherSubscriber(); + scheduledTasksRunner.cancelTasks(); + return Mono.just(new ResponseEntity<>("PRH Service has been stopped!", HttpStatus.OK)); + }); } private ResponseEntity<String> createStartTaskResponse(boolean wasScheduled) { diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/controllers/ScheduleControllerForAutoCommitDisabled.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/controllers/ScheduleControllerForAutoCommitDisabled.java new file mode 100644 index 00000000..64e3a469 --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/controllers/ScheduleControllerForAutoCommitDisabled.java @@ -0,0 +1,80 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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.controllers; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.onap.dcaegen2.services.prh.tasks.commit.ScheduledTasksRunnerWithCommit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; + +/** + * * @author <a href="mailto:PRANIT.KAPDULE@t-systems.com">Pranit Kapdule</a> on + * * 24/08/23 + * */ +@RestController +@Api(value = "ScheduleController") +@Profile("autoCommitDisabled") +public class ScheduleControllerForAutoCommitDisabled { + + private static final Logger LOGGER = LoggerFactory.getLogger(ScheduleControllerForAutoCommitDisabled.class); + + private ScheduledTasksRunnerWithCommit scheduledTasksRunnerWithCommit; + + @Autowired(required = false) + public ScheduleControllerForAutoCommitDisabled(ScheduledTasksRunnerWithCommit scheduledTasksRunnerWithCommit) { + this.scheduledTasksRunnerWithCommit = scheduledTasksRunnerWithCommit; + } + + @RequestMapping(value = "start", method = RequestMethod.GET) + @ApiOperation(value = "Start scheduling worker request") + public Mono<ResponseEntity<String>> startTasks() { + LOGGER.trace("Receiving start scheduling worker request with Comit SchedulerController"); + return Mono.fromSupplier(scheduledTasksRunnerWithCommit::tryToStartTaskWithCommit) + .map(this::createStartTaskResponse); + } + + @RequestMapping(value = "stopPrh", method = RequestMethod.GET) + @ApiOperation(value = "Receiving stop scheduling worker request") + public Mono<ResponseEntity<String>> stopTask() { + LOGGER.trace("Receiving stop scheduling worker request"); + return Mono.defer(() -> { + scheduledTasksRunnerWithCommit.cancelTasks(); + return Mono.just(new ResponseEntity<>("PRH Service has been stopped!", HttpStatus.OK)); + }); + } + + private ResponseEntity<String> createStartTaskResponse(boolean wasScheduled) { + if (wasScheduled) { + return new ResponseEntity<>("PRH Service has been started!", HttpStatus.CREATED); + } else { + return new ResponseEntity<>("PRH Service is already running!", HttpStatus.NOT_ACCEPTABLE); + } + } +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/service/DmaapConsumerJsonParser.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/service/DmaapConsumerJsonParser.java index f98e952f..25c380fb 100644 --- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/service/DmaapConsumerJsonParser.java +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/service/DmaapConsumerJsonParser.java @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2018 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -17,43 +18,48 @@ * limitations under the License. * ============LICENSE_END========================================================= */ - package org.onap.dcaegen2.services.prh.service; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.ADDITIONAL_FIELDS; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.COMMON_EVENT_HEADER; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.COMMON_FORMAT_FOR_JSON_OBJECT; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.COMMON_FORMAT_FOR_STRING; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.CORRELATION_ID; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.EQUIP_MODEL; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.EQUIP_TYPE; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.EQUIP_VENDOR; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.EVENT; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.NF_ROLE; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.OAM_IPV_4_ADDRESS; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.OAM_IPV_6_ADDRESS; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.PNF_REGISTRATION_FIELDS; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.SERIAL_NUMBER; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.SOURCE_NAME; -import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.SW_VERSION; - import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import io.vavr.collection.List; -import java.util.Optional; -import java.util.stream.StreamSupport; import org.onap.dcaegen2.services.prh.adapter.aai.api.ConsumerDmaapModel; import org.onap.dcaegen2.services.prh.adapter.aai.api.ImmutableConsumerDmaapModel; -import org.onap.dcaegen2.services.prh.exceptions.DmaapNotFoundException; import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRouterSubscribeResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.boot.configurationprocessor.json.JSONArray; +import org.springframework.boot.configurationprocessor.json.JSONException; +import org.springframework.boot.configurationprocessor.json.JSONObject; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import java.util.ArrayList; +import java.util.Optional; +import java.util.stream.StreamSupport; + +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.SOURCE_NAME; +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.OAM_IPV_4_ADDRESS; +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.OAM_IPV_6_ADDRESS; +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.SERIAL_NUMBER; +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.EQUIP_VENDOR; +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.EQUIP_MODEL; +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.EQUIP_TYPE; +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.NF_ROLE; +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.SW_VERSION; +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.ADDITIONAL_FIELDS; +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.COMMON_FORMAT_FOR_STRING; +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.EVENT; +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.COMMON_EVENT_HEADER; +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.PNF_REGISTRATION_FIELDS; +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.CORRELATION_ID; +import static org.onap.dcaegen2.services.prh.service.PnfRegistrationFields.COMMON_FORMAT_FOR_JSON_OBJECT; + + + /** * @author <a href="mailto:przemyslaw.wasala@nokia.com">Przemysław Wąsala</a> on 5/8/18 @@ -74,6 +80,8 @@ public class DmaapConsumerJsonParser { private String pnfSwVersionOptionalField; private JsonObject pnfAdditionalFields; + private String sourceName; + /** * Extract info from string and create @see {@link ConsumerDmaapModel}. * @@ -84,6 +92,11 @@ public class DmaapConsumerJsonParser { return monoMessage.flatMapMany(msgRouterResponse -> getConsumerDmaapModelFromJsonArray(msgRouterResponse.items())); } + public JSONObject getJsonObjectKafka(String jsonStr) throws JSONException { + return new JSONObject(jsonStr); + } + + private Flux<ConsumerDmaapModel> getConsumerDmaapModelFromJsonArray(List<JsonElement> items) { LOGGER.debug("DmaapConsumerJsonParser input for parsing: {}", items); @@ -97,25 +110,59 @@ public class DmaapConsumerJsonParser { .orElseGet(JsonObject::new))))); } + /** + * Extract info from string and create @see {@link ConsumerDmaapModel}. + * + * @param monoMessage - results from Kafka + * @return reactive DMaaPModel + * + */ + /** + * @author <a href="mailto:shilpa.urade@t-systems.com">Shilpa Urade</a> on 13/3/23 + */ + + public Flux<ConsumerDmaapModel> getConsumerDmaapModelFromKafkaConsumerRecord(java.util.List<String> items) + { + LOGGER.info("DmaapConsumerJsonParser input for parsing: {} with commit", items); + if (items.size() == 0) { + LOGGER.info("Nothing to consume from Kafka"); + return Flux.empty(); + } + return create( + Flux.defer(() -> Flux.fromStream(StreamSupport.stream(items.spliterator(), false) + .map(jsonObjectFromString -> getJsonObjectFromString(jsonObjectFromString) + .orElseGet(JsonObject::new))))); + } + + Optional<JsonObject> getJsonObjectFromString(String element) { + return Optional.ofNullable(JsonParser.parseString(element).getAsJsonObject()); + } + + public String getSourceName() { + return sourceName; + } + Optional<JsonObject> getJsonObjectFromAnArray(JsonElement element) { JsonParser jsonParser = new JsonParser(); return element.isJsonPrimitive() ? Optional.of(jsonParser.parse(element.getAsString()).getAsJsonObject()) - : Optional.of(jsonParser.parse(element.toString()).getAsJsonObject()); + : Optional.of(jsonParser.parse(element.toString()).getAsJsonObject()); + } + + Optional<JsonObject> getJsonObjectFromKafkaRecords(String element) { + return Optional.ofNullable(new JsonObject().getAsJsonObject(element)); } + private Flux<ConsumerDmaapModel> create(Flux<JsonObject> jsonObject) { - return jsonObject.flatMap(monoJsonP -> - !containsHeader(monoJsonP) ? logErrorAndReturnMonoEmpty("Incorrect JsonObject - missing header") - : transform(monoJsonP)) - .onErrorResume(exception -> exception instanceof DmaapNotFoundException, e -> Mono.empty()); + return jsonObject.flatMap(monoJsonP -> !containsHeader(monoJsonP) ? logErrorAndReturnMonoEmpty("Incorrect JsonObject - missing header") + : transform(monoJsonP)); } private Mono<ConsumerDmaapModel> transform(JsonObject responseFromDmaap) { JsonObject commonEventHeader = responseFromDmaap.getAsJsonObject(EVENT) - .getAsJsonObject(COMMON_EVENT_HEADER); + .getAsJsonObject(COMMON_EVENT_HEADER); JsonObject pnfRegistrationFields = responseFromDmaap.getAsJsonObject(EVENT) - .getAsJsonObject(PNF_REGISTRATION_FIELDS); - + .getAsJsonObject(PNF_REGISTRATION_FIELDS); this.pnfSourceName = getValueFromJson(commonEventHeader, SOURCE_NAME); this.pnfNfRoleOptionalField = getValueFromJson(commonEventHeader, NF_ROLE); this.pnfOamIpv4Address = getValueFromJson(pnfRegistrationFields, OAM_IPV_4_ADDRESS); @@ -126,21 +173,20 @@ public class DmaapConsumerJsonParser { this.pnfEquipTypeOptionalField = getValueFromJson(pnfRegistrationFields, EQUIP_TYPE); this.pnfSwVersionOptionalField = getValueFromJson(pnfRegistrationFields, SW_VERSION); this.pnfAdditionalFields = pnfRegistrationFields.getAsJsonObject(ADDITIONAL_FIELDS); - return (StringUtils.isEmpty(pnfSourceName)) - ? logErrorAndReturnMonoEmpty("Incorrect json, consumerDmaapModel can not be created: " - + printMessage()) : - Mono.just(ImmutableConsumerDmaapModel.builder() - .correlationId(pnfSourceName) - .ipv4(pnfOamIpv4Address) - .ipv6(pnfOamIpv6Address) - .serialNumber(pnfSerialNumberOptionalField) - .equipVendor(pnfEquipVendorOptionalField) - .equipModel(pnfEquipModelOptionalField) - .equipType(pnfEquipTypeOptionalField) - .nfRole(pnfNfRoleOptionalField) - .swVersion(pnfSwVersionOptionalField) - .additionalFields(pnfAdditionalFields).build()); + ? logErrorAndReturnMonoEmpty("Incorrect json, consumerDmaapModel can not be created: " + + printMessage()) : + Mono.just(ImmutableConsumerDmaapModel.builder() + .correlationId(pnfSourceName) + .ipv4(pnfOamIpv4Address) + .ipv6(pnfOamIpv6Address) + .serialNumber(pnfSerialNumberOptionalField) + .equipVendor(pnfEquipVendorOptionalField) + .equipModel(pnfEquipModelOptionalField) + .equipType(pnfEquipTypeOptionalField) + .nfRole(pnfNfRoleOptionalField) + .swVersion(pnfSwVersionOptionalField) + .additionalFields(pnfAdditionalFields).build()); } private String getValueFromJson(JsonObject jsonObject, String jsonKey) { @@ -148,30 +194,39 @@ public class DmaapConsumerJsonParser { } private boolean containsHeader(JsonObject jsonObject) { - return jsonObject.has(EVENT) && jsonObject.getAsJsonObject(EVENT).has(PNF_REGISTRATION_FIELDS); + try { + return jsonObject.has(EVENT) && jsonObject.getAsJsonObject(EVENT).has(PNF_REGISTRATION_FIELDS); + }catch(Exception e){ + LOGGER.info("Fetching an error in containsHeader method {}",e.getMessage()); + } + return false; } private String printMessage() { return String.format("%n{" - + "\"" + CORRELATION_ID + COMMON_FORMAT_FOR_STRING + "," - + "\"" + OAM_IPV_4_ADDRESS + COMMON_FORMAT_FOR_STRING + "," - + "\"" + OAM_IPV_6_ADDRESS + COMMON_FORMAT_FOR_STRING + "," - + "\"" + SERIAL_NUMBER + COMMON_FORMAT_FOR_STRING + "," - + "\"" + EQUIP_VENDOR + COMMON_FORMAT_FOR_STRING + "," - + "\"" + EQUIP_MODEL + COMMON_FORMAT_FOR_STRING + "," - + "\"" + EQUIP_TYPE + COMMON_FORMAT_FOR_STRING + "," - + "\"" + NF_ROLE + COMMON_FORMAT_FOR_STRING + "," - + "\"" + SW_VERSION + COMMON_FORMAT_FOR_STRING + "," - + "\"" + ADDITIONAL_FIELDS + COMMON_FORMAT_FOR_JSON_OBJECT - + "%n}", this.pnfSourceName, this.pnfOamIpv4Address, this.pnfOamIpv6Address, - this.pnfSerialNumberOptionalField, this.pnfEquipVendorOptionalField, - this.pnfEquipModelOptionalField, this.pnfEquipTypeOptionalField, - this.pnfNfRoleOptionalField, this.pnfSwVersionOptionalField, this.pnfAdditionalFields + + "\"" + CORRELATION_ID + COMMON_FORMAT_FOR_STRING + "," + + "\"" + OAM_IPV_4_ADDRESS + COMMON_FORMAT_FOR_STRING + "," + + "\"" + OAM_IPV_6_ADDRESS + COMMON_FORMAT_FOR_STRING + "," + + "\"" + SERIAL_NUMBER + COMMON_FORMAT_FOR_STRING + "," + + "\"" + EQUIP_VENDOR + COMMON_FORMAT_FOR_STRING + "," + + "\"" + EQUIP_MODEL + COMMON_FORMAT_FOR_STRING + "," + + "\"" + EQUIP_TYPE + COMMON_FORMAT_FOR_STRING + "," + + "\"" + NF_ROLE + COMMON_FORMAT_FOR_STRING + "," + + "\"" + SW_VERSION + COMMON_FORMAT_FOR_STRING + "," + + "\"" + ADDITIONAL_FIELDS + COMMON_FORMAT_FOR_JSON_OBJECT + + "%n}", this.pnfSourceName, this.pnfOamIpv4Address, this.pnfOamIpv6Address, + this.pnfSerialNumberOptionalField, this.pnfEquipVendorOptionalField, + this.pnfEquipModelOptionalField, this.pnfEquipTypeOptionalField, + this.pnfNfRoleOptionalField, this.pnfSwVersionOptionalField, this.pnfAdditionalFields ); } private <T> Mono<T> logErrorAndReturnMonoEmpty(String messageForLogger) { - LOGGER.warn(messageForLogger); + LOGGER.info(messageForLogger); return Mono.empty(); } + + public JSONArray getJsonArray(String value) throws JSONException { + return new JSONArray(value); + } } diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiProducerTask.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiProducerTask.java index 35eb948b..ce8059b2 100644 --- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiProducerTask.java +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiProducerTask.java @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2018 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -25,6 +26,6 @@ import org.onap.dcaegen2.services.prh.exceptions.PrhTaskException; import reactor.core.publisher.Mono; @FunctionalInterface -interface AaiProducerTask { +public interface AaiProducerTask { Mono<ConsumerDmaapModel> execute(ConsumerDmaapModel consumerDmaapModel) throws PrhTaskException; } diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTask.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTask.java index 11ff369a..5f86010a 100644 --- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTask.java +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTask.java @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2018 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -23,7 +24,8 @@ package org.onap.dcaegen2.services.prh.tasks; import org.onap.dcaegen2.services.prh.adapter.aai.api.ConsumerDmaapModel; import reactor.core.publisher.Mono; -@FunctionalInterface + public interface AaiQueryTask { Mono<Boolean> execute(final ConsumerDmaapModel aaiModel); + Mono<ConsumerDmaapModel> findPnfinAAI(final ConsumerDmaapModel model); } diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTaskImpl.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTaskImpl.java index 3db4887a..73131926 100644 --- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTaskImpl.java +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTaskImpl.java @@ -3,10 +3,10 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2018 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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 * @@ -35,6 +35,8 @@ import org.onap.dcaegen2.services.prh.model.RelationshipDict; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @Component public class AaiQueryTaskImpl implements AaiQueryTask { @@ -44,6 +46,7 @@ public class AaiQueryTaskImpl implements AaiQueryTask { static final String SERVICE_TYPE = "service-subscription.service-type"; static final String SERVICE_INSTANCE_ID = "service-instance.service-instance-id"; + private static final Logger LOGGER = LoggerFactory.getLogger(AaiQueryTaskImpl.class); private final AaiHttpClient<ConsumerDmaapModel, AaiPnfResultModel> getPnfModelClient; private final AaiHttpClient<AaiServiceInstanceQueryModel, AaiServiceInstanceResultModel> getServiceClient; @@ -55,8 +58,11 @@ public class AaiQueryTaskImpl implements AaiQueryTask { this.getServiceClient = getServiceClient; } + + @Override public Mono<Boolean> execute(ConsumerDmaapModel aaiModel) { + return getPnfModelClient .getAaiResponse(aaiModel) .flatMap(this::checkIfPnfHasRelationToService) @@ -65,7 +71,20 @@ public class AaiQueryTaskImpl implements AaiQueryTask { .defaultIfEmpty(false); } + + // Added by DTAG, March 2023 + @Override + public Mono<ConsumerDmaapModel> findPnfinAAI(final ConsumerDmaapModel model) { + + return getPnfModelClient + .getAaiResponse(model) + .flatMap(aaiModel -> Mono.just(model)); + } + + + private Mono<AaiServiceInstanceQueryModel> checkIfPnfHasRelationToService(final AaiPnfResultModel model) { + return Mono .justOrEmpty(model.getRelationshipList()) .map(this::findRelatedTo) @@ -88,10 +107,12 @@ public class AaiQueryTaskImpl implements AaiQueryTask { } private Boolean checkIfRelatedServiceInstanceIsActive(final AaiServiceInstanceResultModel model) { + return ACTIVE_STATUS.equalsIgnoreCase(model.getOrchestrationStatus()); } private Optional<RelationshipDict> findRelatedTo(final Relationship data) { + return Optional.ofNullable(data.getRelationship()) .map(Stream::of) .orElseGet(Stream::empty) @@ -101,10 +122,12 @@ public class AaiQueryTaskImpl implements AaiQueryTask { } private Optional<String> findValue(final List<RelationshipData> data, final String key) { + return data .stream() .filter(y -> key.equals(y.getRelationshipKey())) .findFirst() .map(RelationshipData::getRelationshipValue); } + } diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/ScheduledTasks.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/ScheduledTasks.java index 68a44ebc..b7c5c7ea 100644 --- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/ScheduledTasks.java +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/ScheduledTasks.java @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2018 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -20,45 +21,51 @@ package org.onap.dcaegen2.services.prh.tasks; -import static org.onap.dcaegen2.services.sdk.rest.services.model.logging.MdcVariables.INSTANCE_UUID; -import static org.onap.dcaegen2.services.sdk.rest.services.model.logging.MdcVariables.RESPONSE_CODE; - -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.CountDownLatch; -import java.util.function.Predicate; import org.onap.dcaegen2.services.prh.adapter.aai.api.ConsumerDmaapModel; import org.onap.dcaegen2.services.prh.exceptions.DmaapEmptyResponseException; import org.onap.dcaegen2.services.prh.exceptions.PrhTaskException; import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRouterPublishResponse; import org.onap.dcaegen2.services.sdk.rest.services.model.logging.MdcVariables; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; -import org.slf4j.Marker; -import org.slf4j.MarkerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Profile; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import java.util.function.Predicate; +import static org.onap.dcaegen2.services.sdk.rest.services.model.logging.MdcVariables.INSTANCE_UUID; +import static org.onap.dcaegen2.services.sdk.rest.services.model.logging.MdcVariables.RESPONSE_CODE; /** * @author <a href="mailto:przemyslaw.wasala@nokia.com">Przemysław Wąsala</a> on 3/23/18 */ +/** + * @author <a href="mailto:sangeeta.bellara@t-systems.com">Sangeeta Bellara</a> on 3/12/23 + */ + +@Profile("!autoCommitDisabled") @Component public class ScheduledTasks { private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledTasks.class); private static final Marker INVOKE = MarkerFactory.getMarker("INVOKE"); - - private final DmaapConsumerTask dmaapConsumerTask; - private final DmaapPublisherTask dmaapReadyProducerTask; - private final DmaapPublisherTask dmaapUpdateProducerTask; - private final AaiQueryTask aaiQueryTask; - private final AaiProducerTask aaiProducerTask; - private final BbsActionsTask bbsActionsTask; + private static Boolean pnfFound = true; + private DmaapConsumerTask dmaapConsumerTask; + + private DmaapPublisherTask dmaapReadyProducerTask; + private DmaapPublisherTask dmaapUpdateProducerTask; + private AaiQueryTask aaiQueryTask; + private AaiProducerTask aaiProducerTask; + private BbsActionsTask bbsActionsTask; private Map<String, String> mdcContextMap; /** @@ -69,6 +76,7 @@ public class ScheduledTasks { * @param dmaapUpdatePublisherTask - fourth task * @param aaiPublisherTask - second task */ + @Autowired public ScheduledTasks( final DmaapConsumerTask dmaapConsumerTask, @@ -90,8 +98,8 @@ public class ScheduledTasks { static class State { public final ConsumerDmaapModel dmaapModel; public final Boolean activationStatus; - - public State(final ConsumerDmaapModel dmaapModel, final Boolean activationStatus) { + + public State(ConsumerDmaapModel dmaapModel, final Boolean activationStatus) { this.dmaapModel = dmaapModel; this.activationStatus = activationStatus; } @@ -139,7 +147,7 @@ public class ScheduledTasks { private void onError(Throwable throwable) { if (!(throwable instanceof DmaapEmptyResponseException)) { - LOGGER.warn("Chain of tasks have been aborted due to errors in PRH workflow", throwable); + LOGGER.warn("Chain of tasks have been aborted due to errors in PRH workflow {}", throwable); } } @@ -153,7 +161,8 @@ public class ScheduledTasks { } private Mono<State> queryAaiForConfiguration(final ConsumerDmaapModel monoDMaaPModel) { - return aaiQueryTask + LOGGER.info("Find AAI Info --> "+monoDMaaPModel.getCorrelationId()); + return aaiQueryTask .execute(monoDMaaPModel) .map(x -> new State(monoDMaaPModel, x)); } 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 70c54a51..5a5eb075 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 @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2018 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -23,44 +24,41 @@ package org.onap.dcaegen2.services.prh.tasks; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ScheduledFuture; - import javax.annotation.PreDestroy; +import org.onap.dcaegen2.services.prh.configuration.CbsConfiguration; import org.onap.dcaegen2.services.prh.configuration.PrhProperties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.Marker; -import org.slf4j.MarkerFactory; import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; import org.springframework.context.event.EventListener; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.annotation.EnableScheduling; - /** * @author <a href="mailto:przemyslaw.wasala@nokia.com">Przemysław Wąsala</a> on 6/13/18 */ + +@Profile("!autoCommitDisabled") @Configuration @EnableScheduling public class ScheduledTasksRunner { - private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledTasksRunner.class); - private static final Marker ENTRY = MarkerFactory.getMarker("ENTRY"); - private static volatile List<ScheduledFuture> scheduledPrhTaskFutureList = new ArrayList<>(); + private static volatile List<ScheduledFuture> scheduledPrhTaskFutureList = new ArrayList<>(); private final TaskScheduler taskScheduler; private final ScheduledTasks scheduledTask; private final PrhProperties prhProperties; - + private final CbsConfiguration cbsConfiguration; public ScheduledTasksRunner(TaskScheduler taskScheduler, ScheduledTasks scheduledTask, - PrhProperties prhProperties) { + PrhProperties prhProperties, CbsConfiguration cbsConfiguration) { this.taskScheduler = taskScheduler; this.scheduledTask = scheduledTask; this.prhProperties = prhProperties; + this.cbsConfiguration = cbsConfiguration; } - + @EventListener public void onApplicationStartedEvent(ApplicationStartedEvent applicationStartedEvent) { - tryToStartTask(); + tryToStartTask(); } /** @@ -78,7 +76,6 @@ public class ScheduledTasksRunner { * @return status of operation execution: true - started, false - not started */ public synchronized boolean tryToStartTask() { - LOGGER.info(ENTRY, "Start scheduling PRH workflow"); if (scheduledPrhTaskFutureList.isEmpty()) { scheduledPrhTaskFutureList.add(taskScheduler .scheduleWithFixedDelay(scheduledTask::scheduleMainPrhEventTask, @@ -88,5 +85,12 @@ public class ScheduledTasksRunner { return false; } } - + + /** + * Function for cleaning resources for kafka subscriber and publisher. + */ + public synchronized void closeKafkaPublisherSubscriber() { + cbsConfiguration.getMessageRouterSubscriber().close(); + cbsConfiguration.getMessageRouterPublisher().close(); + } } diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/commit/EpochDateTimeConversion.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/commit/EpochDateTimeConversion.java new file mode 100644 index 00000000..4bf49208 --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/commit/EpochDateTimeConversion.java @@ -0,0 +1,95 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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.tasks.commit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; + +/** + * This class will return start date time of the day and end date time of the day in epoch format. + * @author <a href="mailto:mohd.khan@t-systems.com">Mohd Usman Khan</a> on 3/13/23 + */ + +@Component +public class EpochDateTimeConversion { + + private static final Logger LOGGER = LoggerFactory.getLogger(EpochDateTimeConversion.class); + + private String daysForRecords = System.getenv("number_of_days"); + + public Long getStartDateOfTheDay(){ + return getEpochDateTime(atStartOfDay(getCurrentDate())); + } + + public Long getEndDateOfTheDay(){ + return getEpochDateTime(atEndOfDay(getCurrentDate())); + } + + private Long getEpochDateTime(Date date) + { + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("E MMM dd HH:mm:ss zzz yyyy"); + ZonedDateTime zdt = ZonedDateTime.parse( date.toString(),dtf); + return zdt.toInstant().toEpochMilli(); + } + + private Date getCurrentDate() + { + return new java.util.Date(System.currentTimeMillis()); + } + + public Date atStartOfDay(Date date) { + LocalDateTime localDateTime = dateToLocalDateTime(date); + if(daysForRecords==null) + daysForRecords="1"; + LocalDateTime previousDay = localDateTime.minusDays(Integer.parseInt(daysForRecords) - 1l); + LocalDateTime previousStartTime = previousDay.with(LocalTime.MIN); + return localDateTimeToDate(previousStartTime); + } + + private Date atEndOfDay(Date date) { + LocalDateTime localDateTime = dateToLocalDateTime(date); + LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX); + return localDateTimeToDate(endOfDay); + } + + private LocalDateTime dateToLocalDateTime(Date date) { + return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); + } + + private Date localDateTimeToDate(LocalDateTime localDateTime) { + return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); + } + + public String getDaysForRecords() { + return daysForRecords; + } + + public void setDaysForRecords(String daysForRecords) { + this.daysForRecords = daysForRecords; + } +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/commit/KafkaConsumerTask.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/commit/KafkaConsumerTask.java new file mode 100644 index 00000000..4c70c713 --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/commit/KafkaConsumerTask.java @@ -0,0 +1,35 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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.tasks.commit; + +import org.onap.dcaegen2.services.prh.adapter.aai.api.ConsumerDmaapModel; +import org.springframework.boot.configurationprocessor.json.JSONException; +import reactor.core.publisher.Flux; + +/** + * @author <a href="mailto:ajinkya-patil@t-systems.com">Ajinkya Patil</a> on 3/13/23 + */ + +public interface KafkaConsumerTask { + Flux<ConsumerDmaapModel> execute() throws JSONException; + + void commitOffset(); +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/commit/KafkaConsumerTaskImpl.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/commit/KafkaConsumerTaskImpl.java new file mode 100644 index 00000000..6b289f1c --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/commit/KafkaConsumerTaskImpl.java @@ -0,0 +1,130 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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.tasks.commit; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.onap.dcaegen2.services.prh.adapter.aai.api.ConsumerDmaapModel; +import org.onap.dcaegen2.services.prh.configuration.CbsConfigurationForAutoCommitDisabledMode; +import org.onap.dcaegen2.services.prh.service.DmaapConsumerJsonParser; +import org.springframework.boot.configurationprocessor.json.JSONException; +import org.springframework.context.annotation.Profile; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.kafka.listener.BatchAcknowledgingMessageListener; +import org.springframework.kafka.support.Acknowledgment; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Flux; +import java.util.ArrayList; +import java.util.List; + +/** + * @author <a href="mailto:ajinkya-patil@t-systems.com">Ajinkya Patil</a> on + * 3/13/23 + */ + +@Profile("autoCommitDisabled") +@Component +public class KafkaConsumerTaskImpl implements KafkaConsumerTask, BatchAcknowledgingMessageListener<String, String> { + + + private DmaapConsumerJsonParser dmaapConsumerJsonParser; + + private EpochDateTimeConversion epochDateTimeConversion; + + private CbsConfigurationForAutoCommitDisabledMode cbsConfigurationForAutoCommitDisabledMode; + + private List<String> jsonEvent = new ArrayList<>(); + + public List<String> getJsonEvent() { + return jsonEvent; + } + + private Acknowledgment offset; + + public Acknowledgment getOffset() { + return offset; + } + + static String commonInURL = "/events/"; + + String kafkaTopic; + + String groupIdConfig; + + + public KafkaConsumerTaskImpl(CbsConfigurationForAutoCommitDisabledMode cbsConfigurationForAutoCommitDisabledMode + ,DmaapConsumerJsonParser dmaapConsumerJsonParser,EpochDateTimeConversion epochDateTimeConversion) { + this.cbsConfigurationForAutoCommitDisabledMode = cbsConfigurationForAutoCommitDisabledMode; + this.dmaapConsumerJsonParser = dmaapConsumerJsonParser; + this.epochDateTimeConversion = epochDateTimeConversion; + String kafkaTopicURL = this.cbsConfigurationForAutoCommitDisabledMode.getMessageRouterSubscribeRequest() + .sourceDefinition().topicUrl(); + kafkaTopic = getTopicFromTopicUrl(kafkaTopicURL); + groupIdConfig = cbsConfigurationForAutoCommitDisabledMode.getMessageRouterSubscribeRequest().consumerGroup(); + + System.setProperty("kafkaTopic", kafkaTopic); + System.setProperty("groupIdConfig", groupIdConfig); + + } + + @Override + @KafkaListener(topics = "${kafkaTopic}", groupId = "${groupIdConfig}") + public void onMessage(List<ConsumerRecord<String, String>> list, Acknowledgment acknowledgment) { + + if (list != null && !list.isEmpty()) { + list.stream().filter( + consumerRecord -> consumerRecord.timestamp() >= epochDateTimeConversion.getStartDateOfTheDay() + && consumerRecord.timestamp() <= epochDateTimeConversion.getEndDateOfTheDay()) + .map(ConsumerRecord::value).forEach(value -> { + jsonEvent.add(value); + }); + + } + + offset = acknowledgment; + } + + @Override + public Flux<ConsumerDmaapModel> execute() throws JSONException { + return dmaapConsumerJsonParser.getConsumerDmaapModelFromKafkaConsumerRecord(jsonEvent); + } + + public void setJsonEvent(List<String> jsonEvent) { + this.jsonEvent = jsonEvent; + } + + @Override + public void commitOffset() { + if (!jsonEvent.isEmpty()) { + jsonEvent.clear(); + } + if (offset != null) { + offset.acknowledge(); + } + } + + public String getTopicFromTopicUrl(String topicUrl) { + if (topicUrl.endsWith("/")) { + return topicUrl.substring(topicUrl.indexOf(commonInURL) + commonInURL.length(), topicUrl.lastIndexOf("/")); + } + return topicUrl.substring(topicUrl.indexOf(commonInURL) + commonInURL.length()); + } + +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/commit/ScheduledTasksRunnerWithCommit.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/commit/ScheduledTasksRunnerWithCommit.java new file mode 100644 index 00000000..91cdd122 --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/commit/ScheduledTasksRunnerWithCommit.java @@ -0,0 +1,98 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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.tasks.commit; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ScheduledFuture; +import javax.annotation.PreDestroy; +import org.onap.dcaegen2.services.prh.configuration.PrhProperties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; +import org.springframework.boot.context.event.ApplicationStartedEvent; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.annotation.EnableScheduling; + +/** + * @author <a href="mailto:pravin.kokane@t-systems.com">Pravin Kokane</a> on 3/13/23 + */ + +@Profile("autoCommitDisabled") +@Configuration +@EnableScheduling +public class ScheduledTasksRunnerWithCommit { + private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledTasksRunnerWithCommit.class); + private static final Marker ENTRY = MarkerFactory.getMarker("ENTRY"); + private static List<ScheduledFuture> scheduledPrhTaskFutureList = new ArrayList<>(); + + private final TaskScheduler taskScheduler; + private final PrhProperties prhProperties; + + private ScheduledTasksWithCommit scheduledTasksWithCommit; + + public ScheduledTasksRunnerWithCommit(TaskScheduler taskScheduler, ScheduledTasksWithCommit scheduledTasksWithCommit, + PrhProperties prhProperties) { + this.taskScheduler = taskScheduler; + this.scheduledTasksWithCommit = scheduledTasksWithCommit; + this.prhProperties = prhProperties; + } + + @EventListener + public void onApplicationStartedEvent(ApplicationStartedEvent applicationStartedEvent) { + LOGGER.info(ENTRY,"### in onApplicationStartedEvent"); + LOGGER.info(ENTRY,"###tryToStartTaskWithCommit="+tryToStartTaskWithCommit()); + } + + /** + * Function which have to stop tasks execution. + */ + @PreDestroy + public synchronized void cancelTasks() { + LOGGER.info(ENTRY,"###In cancelTasks"); + scheduledPrhTaskFutureList.forEach(x -> x.cancel(false)); + scheduledPrhTaskFutureList.clear(); + } + + /** + * Function for starting scheduling PRH workflow. + * + * @return status of operation execution: true - started, false - not started + */ + + public synchronized boolean tryToStartTaskWithCommit() { + LOGGER.info(ENTRY, "Start scheduling PRH workflow with Commit Tasks Runner"); + if (scheduledPrhTaskFutureList.isEmpty()) { + Collections.synchronizedList(scheduledPrhTaskFutureList); + scheduledPrhTaskFutureList.add(taskScheduler + .scheduleWithFixedDelay(scheduledTasksWithCommit::scheduleKafkaPrhEventTask, + prhProperties.getWorkflowSchedulingInterval())); + return true; + } else { + return false; + } + } + +} diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/commit/ScheduledTasksWithCommit.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/commit/ScheduledTasksWithCommit.java new file mode 100644 index 00000000..352c0bbc --- /dev/null +++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/commit/ScheduledTasksWithCommit.java @@ -0,0 +1,203 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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.tasks.commit; + +import static org.onap.dcaegen2.services.sdk.rest.services.model.logging.MdcVariables.RESPONSE_CODE; + +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import org.onap.dcaegen2.services.prh.exceptions.DmaapEmptyResponseException; +import org.onap.dcaegen2.services.prh.exceptions.PrhTaskException; +import org.onap.dcaegen2.services.prh.tasks.AaiProducerTask; +import org.onap.dcaegen2.services.prh.tasks.AaiQueryTask; +import org.onap.dcaegen2.services.prh.tasks.BbsActionsTask; +import org.onap.dcaegen2.services.prh.tasks.DmaapPublisherTask; +import org.onap.dcaegen2.services.prh.adapter.aai.api.ConsumerDmaapModel; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRouterPublishResponse; +import org.onap.dcaegen2.services.sdk.rest.services.model.logging.MdcVariables; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.configurationprocessor.json.JSONException; +import org.springframework.context.annotation.Profile; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * @author <a href="mailto:sangeeta.bellara@t-systems.com">Sangeeta Bellara</a> + * on 3/13/23 + */ +@Profile("autoCommitDisabled") +@Component +public class ScheduledTasksWithCommit { + + private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledTasksWithCommit.class); + private static Boolean pnfFound = true; + private KafkaConsumerTask kafkaConsumerTask; + private DmaapPublisherTask dmaapReadyProducerTask; + private DmaapPublisherTask dmaapUpdateProducerTask; + public AaiQueryTask aaiQueryTask; + private AaiProducerTask aaiProducerTask; + private BbsActionsTask bbsActionsTask; + private Map<String, String> mdcContextMap; + + /** + * Constructor for tasks registration in PRHWorkflow. + * + * @param kafkaConsumerTask - fist task + * @param dmaapReadyPublisherTask - third task + * @param dmaapUpdatePublisherTask - fourth task + * @param aaiPublisherTask - second task + */ + @Autowired + public ScheduledTasksWithCommit(final KafkaConsumerTask kafkaConsumerTask, + @Qualifier("ReadyPublisherTask") final DmaapPublisherTask dmaapReadyPublisherTask, + @Qualifier("UpdatePublisherTask") final DmaapPublisherTask dmaapUpdatePublisherTask, + final AaiQueryTask aaiQueryTask, final AaiProducerTask aaiPublisherTask, + final BbsActionsTask bbsActionsTask, final Map<String, String> mdcContextMap) + + { + this.dmaapReadyProducerTask = dmaapReadyPublisherTask; + this.dmaapUpdateProducerTask = dmaapUpdatePublisherTask; + this.kafkaConsumerTask = kafkaConsumerTask; + this.aaiQueryTask = aaiQueryTask; + this.aaiProducerTask = aaiPublisherTask; + this.bbsActionsTask = bbsActionsTask; + this.mdcContextMap = mdcContextMap; + } + + static class State { + public ConsumerDmaapModel dmaapModel; + public Boolean activationStatus; + + public State(ConsumerDmaapModel dmaapModel, final Boolean activationStatus) { + this.dmaapModel = dmaapModel; + this.activationStatus = activationStatus; + } + } + + public void scheduleKafkaPrhEventTask() { + MdcVariables.setMdcContextMap(mdcContextMap); + try { + + LOGGER.info("Execution of tasks was registered with commit"); + CountDownLatch mainCountDownLatch = new CountDownLatch(1); + consumeFromKafkaMessage() + .flatMap(model -> queryAaiForPnf(model).doOnError(e -> { + LOGGER.info("PNF Not Found in AAI --> {}" + e); + LOGGER.info("PNF Not Found in AAI With description of exception --> {}" + e.getMessage()); + disableCommit(); + }).onErrorResume(e -> Mono.empty()) + + ) + .flatMap(this::queryAaiForConfiguration) + .flatMap(this::publishToAaiConfiguration) + .flatMap(this::processAdditionalFields).flatMap(this::publishToDmaapConfiguration) + + .onErrorResume(e -> Mono.empty()) + + .doOnTerminate(mainCountDownLatch::countDown) + .subscribe(this::onSuccess, this::onError, this::onCompleteKafka); + mainCountDownLatch.await(); + } catch (InterruptedException | JSONException e) { + LOGGER.warn("Interruption problem on countDownLatch {}", e); + Thread.currentThread().interrupt(); + } + } + + private static void disableCommit() { + pnfFound = false; + } + + private void onCompleteKafka() { + LOGGER.info("PRH tasks have been completed"); + if (pnfFound) { + kafkaConsumerTask.commitOffset(); + LOGGER.info("Committed the Offset"); + } else { + LOGGER.info("Offset not Committed"); + pnfFound = true; + } + } + + private void onSuccess(MessageRouterPublishResponse response) { + if (response.successful()) { + String statusCodeOk = HttpStatus.OK.name(); + MDC.put(RESPONSE_CODE, statusCodeOk); + LOGGER.info("Prh consumed tasks successfully. HTTP Response code from DMaaPProducer {}", statusCodeOk); + MDC.remove(RESPONSE_CODE); + } + } + + private void onError(Throwable throwable) { + if (!(throwable instanceof DmaapEmptyResponseException)) { + LOGGER.warn("Chain of tasks have been aborted due to errors in PRH workflow {}", throwable); + } + } + + private Flux<ConsumerDmaapModel> consumeFromKafkaMessage() throws JSONException { + return kafkaConsumerTask.execute(); + } + + private Mono<State> queryAaiForConfiguration(final ConsumerDmaapModel monoDMaaPModel) { + return aaiQueryTask.execute(monoDMaaPModel).map(x -> new State(monoDMaaPModel, x)); + } + + private Mono<ConsumerDmaapModel> queryAaiForPnf(final ConsumerDmaapModel monoDMaaPModel) { + + LOGGER.info("Find PNF --> " + monoDMaaPModel.getCorrelationId()); + return aaiQueryTask.findPnfinAAI(monoDMaaPModel); + } + + private Mono<State> publishToAaiConfiguration(final State state) { + try { + return aaiProducerTask.execute(state.dmaapModel).map(x -> state); + } catch (PrhTaskException e) { + LOGGER.warn("AAIProducerTask exception has been registered: {}", e); + return Mono.error(e); + } + } + + private Mono<State> processAdditionalFields(final State state) { + if (state.activationStatus) { + LOGGER.debug("Re-registration - Logical links won't be updated."); + return Mono.just(state); + } + return bbsActionsTask.execute(state.dmaapModel).map(x -> state); + } + + private Flux<MessageRouterPublishResponse> publishToDmaapConfiguration(final State state) { + try { + if (state.activationStatus) { + LOGGER.debug("Re-registration - Using PNF_UPDATE DMaaP topic."); + return dmaapUpdateProducerTask.execute(state.dmaapModel); + } + return dmaapReadyProducerTask.execute(state.dmaapModel); + } catch (PrhTaskException e) { + LOGGER.warn("DMaaPProducerTask exception has been registered: ", e); + return Flux.error(e); + } + } +} diff --git a/prh-app-server/src/main/resources/application.yaml b/prh-app-server/src/main/resources/application.yaml index 8f1950d0..e62d4e90 100644 --- a/prh-app-server/src/main/resources/application.yaml +++ b/prh-app-server/src/main/resources/application.yaml @@ -1,6 +1,6 @@ spring: - profiles: - active: prod + profiles: prod + server: port: 8433 ssl: @@ -25,4 +25,13 @@ logging: management.endpoints.web.exposure.include: "*" +--- +spring: + profiles: + default: prod + + + + + diff --git a/prh-app-server/src/main/resources/logback-spring.xml b/prh-app-server/src/main/resources/logback-spring.xml index 060cf6c5..c4d31e52 100644 --- a/prh-app-server/src/main/resources/logback-spring.xml +++ b/prh-app-server/src/main/resources/logback-spring.xml @@ -1,8 +1,27 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ ============LICENSE_START======================================================= + ~ PNF-REGISTRATION-HANDLER + ~ ================================================================================ + ~ Copyright (C) 2023 Deutsche Telekom 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========================================================= +--> <configuration debug="false" scan="false"> <include resource="org/springframework/boot/logging/logback/defaults.xml"/> <property name="outputFilename" value="prh-app-server_output"/> - <property name="logPath" value="/var/log/ONAP/prh/prh-app-server"/> + <property name="logPath" value="/var/log/ONAP/prh/prh-app-server"/> <property name="archivePath" value="${logPath}/archive"/> <property name="maxFileSize" value="50MB"/> <property name="maxHistory" value="30"/> @@ -17,7 +36,7 @@ |%thread |%n"/> - <springProfile name="prod"> + <springProfile name="prod,autoCommitDisabled"> <appender class="ch.qos.logback.core.ConsoleAppender" name="CONSOLE" target="SYSTEM_OUT"> <encoder> <pattern>${defaultPattern}</pattern> diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/bootstrap/CbsClientConfigurationResolverTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/bootstrap/CbsClientConfigurationResolverTest.java index 87dd18ca..ca1413a0 100644 --- a/prh-app-server/src/test/java/org/onap/dcaegen2/services/bootstrap/CbsClientConfigurationResolverTest.java +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/bootstrap/CbsClientConfigurationResolverTest.java @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -24,7 +25,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable; import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.CbsClientConfiguration; - import static org.assertj.core.api.Assertions.assertThat; class CbsClientConfigurationResolverTest { @@ -34,18 +34,15 @@ class CbsClientConfigurationResolverTest { @BeforeEach void setUp() { cbsProperties = new CbsProperties(); - cbsProperties.setHostname("some-cbs-host"); - cbsProperties.setPort(123); cbsProperties.setAppName("client-app-name"); } @Test @DisabledIfEnvironmentVariable(named = "CONFIG_BINDING_SERVICE", matches = ".+") void whenCbsEnvPropertiesAreNotePresentInEnvironment_ShouldFallbackToLoadingDefaultsFromCbsProperties() { - CbsClientConfiguration config = new CbsClientConfigurationResolver(cbsProperties).resolveCbsClientConfiguration(); + CbsClientConfiguration config = new CbsClientConfigurationResolver(cbsProperties) + .resolveCbsClientConfiguration(); - assertThat(config.hostname()).isEqualTo(cbsProperties.getHostname()); - assertThat(config.port()).isEqualTo(cbsProperties.getPort()); assertThat(config.appName()).isEqualTo(cbsProperties.getAppName()); } -}
\ No newline at end of file +} diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/bootstrap/CbsPropertySourceLocatorForAutoCommitDisabledTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/bootstrap/CbsPropertySourceLocatorForAutoCommitDisabledTest.java new file mode 100644 index 00000000..f5863ac5 --- /dev/null +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/bootstrap/CbsPropertySourceLocatorForAutoCommitDisabledTest.java @@ -0,0 +1,112 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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 static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import java.util.Map; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.onap.dcaegen2.services.prh.configuration.CbsConfiguration; +import org.onap.dcaegen2.services.prh.configuration.CbsConfigurationForAutoCommitDisabledMode; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsClient; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsRequests; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.RequestPath; +import org.onap.dcaegen2.services.sdk.rest.services.model.logging.RequestDiagnosticContext; +import org.springframework.core.env.Environment; +import org.springframework.test.context.ActiveProfiles; +import com.google.common.collect.ImmutableMap; +import com.google.gson.JsonObject; +import reactor.core.publisher.Mono; +import reactor.test.scheduler.VirtualTimeScheduler; + +/** + * * @author <a href="mailto:PRANIT.KAPDULE@t-systems.com">Pranit Kapdule</a> on + * * 24/08/23 + * */ + +@ExtendWith(MockitoExtension.class) +@ActiveProfiles(value = "autoCommitDisabled") +public class CbsPropertySourceLocatorForAutoCommitDisabledTest { + private static final RequestPath GET_ALL_REQUEST_PATH = CbsRequests.getAll(RequestDiagnosticContext.create()) + .requestPath(); + + private CbsProperties cbsProperties = new CbsProperties(); + @Mock + private CbsJsonToPropertyMapConverter cbsJsonToPropertyMapConverter; + @Mock + private CbsClientConfigurationResolver cbsClientConfigurationResolver; + @Mock + private CbsClientFactoryFacade cbsClientFactoryFacade; + @Mock + private CbsConfiguration cbsConfiguration; + @Mock + private CbsConfigurationForAutoCommitDisabledMode cbsConfigurationForAutoCommitDisabledMode; + @Mock + private Environment environment; + @Mock + private CbsClient cbsClient; + @Mock + private JsonObject cbsConfigJsonObject; + + private Map<String, Object> cbsConfigMap = ImmutableMap.of("foo", "bar"); + + private VirtualTimeScheduler virtualTimeScheduler; + + private CbsPropertySourceLocatorForAutoCommitDisabled cbsPropertySourceLocatorACDM; + + @BeforeEach + void setup() { + virtualTimeScheduler = VirtualTimeScheduler.getOrSet(true); + + cbsPropertySourceLocatorACDM = new CbsPropertySourceLocatorForAutoCommitDisabled(cbsProperties, + cbsJsonToPropertyMapConverter, cbsClientConfigurationResolver, cbsClientFactoryFacade, + cbsConfigurationForAutoCommitDisabledMode); + + } + + @AfterEach + void cleanup() { + virtualTimeScheduler.dispose(); + } + + @Test + void cbsProperySourceLocatorForAutoCommitDisabledTest() throws Exception { + + Mono<CbsClient> just = Mono.just(cbsClient); + when(cbsClientFactoryFacade.createCbsClient(any())).thenReturn(just); + when(cbsClient.get(argThat(request -> request.requestPath().equals(GET_ALL_REQUEST_PATH)))) + .thenReturn(Mono.just(cbsConfigJsonObject)); + when(cbsJsonToPropertyMapConverter.convertToMap(cbsConfigJsonObject)).thenReturn(cbsConfigMap); + + cbsPropertySourceLocatorACDM.locate(environment); + + verify(cbsConfigurationForAutoCommitDisabledMode).parseCBSConfig(cbsConfigJsonObject); + + + } + +} diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/bootstrap/CbsPropertySourceLocatorTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/bootstrap/CbsPropertySourceLocatorTest.java index 22a11ed6..c1e938e5 100644 --- a/prh-app-server/src/test/java/org/onap/dcaegen2/services/bootstrap/CbsPropertySourceLocatorTest.java +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/bootstrap/CbsPropertySourceLocatorTest.java @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2019-2021 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -29,6 +30,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.onap.dcaegen2.services.prh.configuration.CbsConfiguration; +import org.onap.dcaegen2.services.prh.configuration.CbsConfigurationForAutoCommitDisabledMode; import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsClient; import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsRequests; import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.CbsClientConfiguration; @@ -39,20 +41,21 @@ import org.springframework.core.env.Environment; import org.springframework.core.env.PropertySource; import reactor.core.publisher.Mono; import reactor.test.scheduler.VirtualTimeScheduler; - import java.util.Map; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assumptions.assumeThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.*; - +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.doThrow; @ExtendWith(MockitoExtension.class) class CbsPropertySourceLocatorTest { - private static final RequestPath GET_ALL_REQUEST_PATH = CbsRequests.getAll(RequestDiagnosticContext.create()).requestPath(); + private static final RequestPath GET_ALL_REQUEST_PATH = CbsRequests.getAll(RequestDiagnosticContext.create()) + .requestPath(); private CbsProperties cbsProperties = new CbsProperties(); @Mock @@ -66,28 +69,24 @@ class CbsPropertySourceLocatorTest { @Mock private CbsConfiguration cbsConfiguration; @Mock + private CbsConfigurationForAutoCommitDisabledMode cbsConfigurationForAutoCommitDisabledMode; + @Mock private Environment environment; @Mock private CbsClient cbsClient; @Mock private JsonObject cbsConfigJsonObject; private Map<String, Object> cbsConfigMap = ImmutableMap.of("foo", "bar"); - private VirtualTimeScheduler virtualTimeScheduler; - private CbsPropertySourceLocator cbsPropertySourceLocator; - @BeforeEach void setup() { virtualTimeScheduler = VirtualTimeScheduler.getOrSet(true); - when(cbsClientConfigurationResolver.resolveCbsClientConfiguration()).thenReturn(cbsClientConfiguration); - when(cbsClientFactoryFacade.createCbsClient(cbsClientConfiguration)).thenReturn(Mono.just(cbsClient)); + cbsPropertySourceLocator = new CbsPropertySourceLocator(cbsProperties, cbsJsonToPropertyMapConverter, + cbsClientConfigurationResolver, cbsClientFactoryFacade, cbsConfiguration); - cbsPropertySourceLocator = new CbsPropertySourceLocator( - cbsProperties, cbsJsonToPropertyMapConverter, cbsClientConfigurationResolver, - cbsClientFactoryFacade, cbsConfiguration); } @AfterEach @@ -95,9 +94,10 @@ class CbsPropertySourceLocatorTest { virtualTimeScheduler.dispose(); } - @Test void shouldBuildCbsPropertySourceBasedOnDataFetchedUsingCbsClient() { + Mono<CbsClient> just = Mono.just(cbsClient); + when(cbsClientFactoryFacade.createCbsClient(any())).thenReturn(just); when(cbsClient.get(argThat(request -> request.requestPath().equals(GET_ALL_REQUEST_PATH)))) .thenReturn(Mono.just(cbsConfigJsonObject)); when(cbsJsonToPropertyMapConverter.convertToMap(cbsConfigJsonObject)).thenReturn(cbsConfigMap); @@ -108,9 +108,10 @@ class CbsPropertySourceLocatorTest { assertThat(propertySource).extracting(s -> s.getProperty("foo")).isEqualTo("bar"); } - @Test void shouldUpdateCbsConfigurationStateBasedOnDataFetchedUsingCbsClient() { + Mono<CbsClient> just = Mono.just(cbsClient); + when(cbsClientFactoryFacade.createCbsClient(any())).thenReturn(just); when(cbsClient.get(argThat(request -> request.requestPath().equals(GET_ALL_REQUEST_PATH)))) .thenReturn(Mono.just(cbsConfigJsonObject)); when(cbsJsonToPropertyMapConverter.convertToMap(cbsConfigJsonObject)).thenReturn(cbsConfigMap); @@ -120,9 +121,10 @@ class CbsPropertySourceLocatorTest { verify(cbsConfiguration).parseCBSConfig(cbsConfigJsonObject); } - @Test void shouldPropagateExceptionWhenCbsConfigurationParsingFails() { + Mono<CbsClient> just = Mono.just(cbsClient); + when(cbsClientFactoryFacade.createCbsClient(any())).thenReturn(just); when(cbsClient.get(any(CbsRequest.class))).thenReturn(Mono.just(cbsConfigJsonObject)); RuntimeException someCbsConfigParsingException = new RuntimeException("boom!"); @@ -134,13 +136,13 @@ class CbsPropertySourceLocatorTest { @Test void shouldRetryFetchingConfigFromCbsInCaseOfFailure() { + Mono<CbsClient> just = Mono.just(cbsClient); + when(cbsClientFactoryFacade.createCbsClient(any())).thenReturn(just); assumeThat(cbsProperties.getFetchRetries().getMaxAttempts()).isGreaterThan(1); - when(cbsClient.get(any(CbsRequest.class))) - .thenReturn(Mono.defer(() -> { - virtualTimeScheduler.advanceTimeBy(cbsProperties.getFetchRetries().getMaxBackoff()); - return Mono.error(new RuntimeException("some connection failure")); - })) - .thenReturn(Mono.just(cbsConfigJsonObject)); + when(cbsClient.get(any(CbsRequest.class))).thenReturn(Mono.defer(() -> { + virtualTimeScheduler.advanceTimeBy(cbsProperties.getFetchRetries().getMaxBackoff()); + return Mono.error(new RuntimeException("some connection failure")); + })).thenReturn(Mono.just(cbsConfigJsonObject)); when(cbsJsonToPropertyMapConverter.convertToMap(cbsConfigJsonObject)).thenReturn(cbsConfigMap); PropertySource<?> propertySource = cbsPropertySourceLocator.locate(environment); @@ -150,15 +152,16 @@ class CbsPropertySourceLocatorTest { @Test void shouldFailAfterExhaustingAllOfConfiguredRetryAttempts() { + Mono<CbsClient> just = Mono.just(cbsClient); + when(cbsClientFactoryFacade.createCbsClient(any())).thenReturn(just); assumeThat(cbsProperties.getFetchRetries().getMaxAttempts()).isGreaterThan(1); - when(cbsClient.get(any(CbsRequest.class))) - .thenReturn(Mono.defer(() -> { - virtualTimeScheduler.advanceTimeBy(cbsProperties.getFetchRetries().getMaxBackoff()); - return Mono.error(new RuntimeException("some connection failure")); - })); + when(cbsClient.get(any(CbsRequest.class))).thenReturn(Mono.defer(() -> { + virtualTimeScheduler.advanceTimeBy(cbsProperties.getFetchRetries().getMaxBackoff()); + return Mono.error(new RuntimeException("some connection failure")); + })); - assertThatThrownBy(() -> cbsPropertySourceLocator.locate(environment)) - .hasMessageContaining("Retries exhausted") + assertThatThrownBy(() -> cbsPropertySourceLocator.locate(environment)).hasMessageContaining("Retries exhausted") .hasMessageContaining(cbsProperties.getFetchRetries().getMaxAttempts().toString()); } + } diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/configuration/CbsConfigurationForAutoCommitDisabledModeTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/configuration/CbsConfigurationForAutoCommitDisabledModeTest.java new file mode 100644 index 00000000..80a0007f --- /dev/null +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/configuration/CbsConfigurationForAutoCommitDisabledModeTest.java @@ -0,0 +1,111 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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 static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable; +import static java.lang.ClassLoader.getSystemResource; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.nio.file.Files; +import java.nio.file.Paths; +import org.junit.jupiter.api.Test; +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +/** + * * @author <a href="mailto:PRANIT.KAPDULE@t-systems.com">Pranit Kapdule</a> on + * * 24/08/23 + * */ + +public class CbsConfigurationForAutoCommitDisabledModeTest { + + /** + * Testcase is used to check correctness of values provided by + * autoCommitDisabledConfigurationFromCbs2.json + */ + + @Test + void beforecbsConfigurationForAutoCommitDisabledMode() throws Exception { + withEnvironmentVariable("JAAS_CONFIG", "jaas_config") + .and("BOOTSTRAP_SERVERS", "localhost:9092") + .execute(() -> { + this.cbsConfigurationForAutoCommitDisabledMode(); + }); + } + + void cbsConfigurationForAutoCommitDisabledMode() throws Exception { + + JsonObject cbsConfigJsonForAutoCommitDisabled = new Gson().fromJson( + new String(Files.readAllBytes( + Paths.get(getSystemResource("autoCommitDisabledConfigurationFromCbs2.json").toURI()))), + JsonObject.class); + CbsConfigurationForAutoCommitDisabledMode cbsConfigurationForAutoCommitDisabled = new CbsConfigurationForAutoCommitDisabledMode(); + + cbsConfigurationForAutoCommitDisabled.parseCBSConfig(cbsConfigJsonForAutoCommitDisabled); + + String expectedKafKaBoostrapServerConfig = "onap-strimzi-kafka-bootstrap:9092"; + String actualKafkaBoostrapServerConfig = (cbsConfigurationForAutoCommitDisabled.getKafkaConfig() + .kafkaBoostrapServerConfig()); + + String expectedGroupIdConfig = "OpenDCAE-c12"; + String actualGroupIdConfig = (cbsConfigurationForAutoCommitDisabled.getKafkaConfig().groupIdConfig()); + + String expectedKafkaSecurityProtocol = "SASL_PLAINTEXT"; + String actualKafkaSecurityProtocol = (cbsConfigurationForAutoCommitDisabled.getKafkaConfig() + .kafkaSecurityProtocol()); + + String expectedKafkaSaslMechanism = "SCRAM-SHA-512"; + String actualKafkaSaslMechanism = (cbsConfigurationForAutoCommitDisabled.getKafkaConfig().kafkaSaslMechanism()); + + String expectedKafkaJaasConfig = "jaas_config"; + String actualKafkaJaasConfig = (cbsConfigurationForAutoCommitDisabled.getKafkaConfig().kafkaJaasConfig()); + + String expectedAaiUserName = "AAI"; + String actualAaiUserName = (cbsConfigurationForAutoCommitDisabled.getAaiClientConfiguration().aaiUserName()); + + String expectedConsumerGroup = "OpenDCAE-c12"; + String actualConsumerGroup = (cbsConfigurationForAutoCommitDisabled.getMessageRouterSubscribeRequest() + .consumerGroup()); + + assertEquals(expectedKafKaBoostrapServerConfig, actualKafkaBoostrapServerConfig, + "Expected value of KafKaBoostrapServerConfig is not matching with actual value"); + assertEquals(expectedGroupIdConfig, actualGroupIdConfig, + "Expected value of GroupIdConfig is not matching with actual value"); + assertEquals(expectedKafkaSecurityProtocol, actualKafkaSecurityProtocol, + "Expected value of KafkaSecurityProtocol is not matching with actual value"); + assertEquals(expectedKafkaSaslMechanism, actualKafkaSaslMechanism, + "Expected value of KafkaSaslMechanism is not matching with actual value"); + assertEquals(expectedKafkaJaasConfig, actualKafkaJaasConfig, + "Expected value of KafkaJaasConfig is not matching with actual value"); + assertEquals(expectedAaiUserName, actualAaiUserName, + "Expected value of AaiUserName is not matching with actual value"); + assertEquals(expectedConsumerGroup, actualConsumerGroup, + "Expected value of ConsumerGroup is not matching with actual value"); + + assertThat((cbsConfigurationForAutoCommitDisabled).getAaiClientConfiguration()).isNotNull(); + assertThat((cbsConfigurationForAutoCommitDisabled).getMessageRouterPublisher()).isNotNull(); + assertThat((cbsConfigurationForAutoCommitDisabled).getMessageRouterSubscriber()).isNotNull(); + assertThat((cbsConfigurationForAutoCommitDisabled).getMessageRouterPublishRequest()).isNotNull(); + assertThat((cbsConfigurationForAutoCommitDisabled).getMessageRouterSubscribeRequest()).isNotNull(); + assertThat((cbsConfigurationForAutoCommitDisabled).getMessageRouterUpdatePublishRequest()).isNotNull(); + + } + +} diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/configuration/CbsConfigurationTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/configuration/CbsConfigurationTest.java index 7f5d26fc..8cd7d5e8 100644 --- a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/configuration/CbsConfigurationTest.java +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/configuration/CbsConfigurationTest.java @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -23,10 +24,10 @@ package org.onap.dcaegen2.services.prh.configuration; import com.google.gson.Gson; import com.google.gson.JsonObject; import org.junit.jupiter.api.Test; - import java.nio.file.Files; import java.nio.file.Paths; +import static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable; import static java.lang.ClassLoader.getSystemResource; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -51,20 +52,29 @@ class CbsConfigurationTest { .hasMessage(EXPECTED_ERROR_MESSAGE_WHEN_CBS_CONFIG_IS_NOT_INITIALIZED); } - @Test void cbsConfigurationShouldExposeDataReceivedAsJsonFromCbs() throws Exception { - JsonObject cbsConfigJson = new Gson().fromJson(new String(Files.readAllBytes(Paths.get( - getSystemResource("configurationFromCbs.json").toURI()))), JsonObject.class); - CbsConfiguration cbsConfiguration = new CbsConfiguration(); + + withEnvironmentVariable("JAAS_CONFIG", "jaas_config") + .and("BOOTSTRAP_SERVERS", "localhost:9092") + .execute(() -> { + JsonObject cbsConfigJson = new Gson().fromJson( + new String(Files.readAllBytes(Paths.get(getSystemResource("configurationFromCbs.json").toURI()))), + JsonObject.class); + CbsConfiguration cbsConfiguration = new CbsConfiguration(); - cbsConfiguration.parseCBSConfig(cbsConfigJson); + cbsConfiguration.parseCBSConfig(cbsConfigJson); + + assertThat(cbsConfiguration.getAaiClientConfiguration()).isNotNull(); + assertThat(cbsConfiguration.getMessageRouterPublisher()).isNotNull(); + assertThat(cbsConfiguration.getMessageRouterSubscriber()).isNotNull(); + assertThat(cbsConfiguration.getMessageRouterPublishRequest()).isNotNull(); + assertThat(cbsConfiguration.getMessageRouterSubscribeRequest()).isNotNull(); + assertThat(cbsConfiguration.getMessageRouterUpdatePublishRequest()).isNotNull(); + }); + - assertThat(cbsConfiguration.getAaiClientConfiguration()).isNotNull(); - assertThat(cbsConfiguration.getMessageRouterPublisher()).isNotNull(); - assertThat(cbsConfiguration.getMessageRouterSubscriber()).isNotNull(); - assertThat(cbsConfiguration.getMessageRouterPublishRequest()).isNotNull(); - assertThat(cbsConfiguration.getMessageRouterSubscribeRequest()).isNotNull(); - assertThat(cbsConfiguration.getMessageRouterUpdatePublishRequest()).isNotNull(); } -}
\ No newline at end of file + + +} diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/configuration/KafkaConfigTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/configuration/KafkaConfigTest.java new file mode 100644 index 00000000..b9a05a99 --- /dev/null +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/configuration/KafkaConfigTest.java @@ -0,0 +1,140 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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 static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable; +import static java.lang.ClassLoader.getSystemResource; +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.nio.file.Files; +import java.nio.file.Paths; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.kafka.core.ConsumerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +@ExtendWith(MockitoExtension.class) +public class KafkaConfigTest { + + KafkaConfig kafkaConfig = new KafkaConfig(); + + CbsConfigurationForAutoCommitDisabledMode cbsConfigurationForAutoCommitDisabledMode = new + CbsConfigurationForAutoCommitDisabledMode(); + + +// @BeforeEach +// void setUp() { +// kafkaConfig.kafkaBoostrapServerConfig = "0.0.0.0"; +// kafkaConfig.groupIdConfig = "consumer-test"; +// kafkaConfig.kafkaSecurityProtocol = "test"; +// kafkaConfig.kafkaSaslMechanism = "test"; +// kafkaConfig.kafkaUsername = "test"; +// kafkaConfig.kafkaPassword = "test"; +// kafkaConfig.kafkaJaasConfig = null; +// kafkaConfig.kafkaLoginModuleClassConfig = "test"; +// kafkaConfig.kafkaJaasConfig = "test"; +// } + + @Test + void beforecbsConfigurationForAutoCommitDisabledMode() throws Exception { + withEnvironmentVariable("JAAS_CONFIG", "jaas_config") + .and("BOOTSTRAP_SERVERS", "localhost:9092") + .execute(() -> { + this.consumerFactoryTest(); + }); + } + + void consumerFactoryTest() throws Exception { + JsonObject cbsConfigJsonForAutoCommitDisabled = new Gson().fromJson( + new String(Files.readAllBytes( + Paths.get(getSystemResource("autoCommitDisabledConfigurationFromCbs2.json").toURI()))), + JsonObject.class); + cbsConfigurationForAutoCommitDisabledMode.parseCBSConfig(cbsConfigJsonForAutoCommitDisabled); + ConsumerFactory<String, String> consumerFactory = kafkaConfig + .consumerFactory(cbsConfigurationForAutoCommitDisabledMode); + + String expectedKafkaBoostrapServerConfig = "onap-strimzi-kafka-bootstrap:9092"; + String actualKafkaBoostrapServerConfig = consumerFactory.getConfigurationProperties().get("bootstrap.servers") + .toString(); + + String expectedGroupIdConfig = "OpenDCAE-c12"; + String actualGroupIdConfig = consumerFactory.getConfigurationProperties().get("group.id").toString(); + + String expectedKafkaSecurityProtocol = "SASL_PLAINTEXT"; + String actualKafkaSecurityProtocol = consumerFactory.getConfigurationProperties().get("security.protocol") + .toString(); + + String expectedKafkaSaslMechanism = "SCRAM-SHA-512"; + String actualKafkaSaslMechanism = consumerFactory.getConfigurationProperties().get("sasl.mechanism").toString(); + + String expectedKafkaJaasConfig = "jaas_config"; + String actualKafkaJaasConfig = consumerFactory.getConfigurationProperties().get("sasl.jaas.config").toString(); + + String expectedKeyDeserializer = "org.apache.kafka.common.serialization.StringDeserializer"; + String actualKeyDeserializer = consumerFactory.getConfigurationProperties().get("key.deserializer").toString(); + + String expectedValueDeserializer = "org.apache.kafka.common.serialization.StringDeserializer"; + String actualValueDeserializer = consumerFactory.getConfigurationProperties().get("value.deserializer") + .toString(); + + String expectedEnableAutoCommit = "false"; + String actualEnableAutoCommit = consumerFactory.getConfigurationProperties().get("enable.auto.commit") + .toString(); + + assertEquals(expectedKafkaBoostrapServerConfig, actualKafkaBoostrapServerConfig, + "Expected value of KafKaBoostrapServerConfig is not matching with actual value"); + assertEquals(expectedGroupIdConfig, actualGroupIdConfig, + "Expected value of GroupIdConfig is not matching with actual value"); + assertEquals(expectedKafkaSecurityProtocol, actualKafkaSecurityProtocol, + "Expected value of KafkaSecurityProtocol is not matching with actual value"); + assertEquals(expectedKafkaSaslMechanism, actualKafkaSaslMechanism, + "Expected value of KafkaSaslMechanism is not matching with actual value"); + assertEquals(expectedKafkaJaasConfig, actualKafkaJaasConfig, + "Expected value of KafkaJaasConfig is not matching with actual value"); + assertEquals(expectedKeyDeserializer, actualKeyDeserializer, + "Expected value of KeyDeserializer is not matching with actual value"); + assertEquals(expectedValueDeserializer, actualValueDeserializer, + "Expected value of ValueDeserializer is not matching with actual value"); + assertEquals(expectedEnableAutoCommit, actualEnableAutoCommit, + "Expected value of EnableAutoCommit is not matching with actual value"); + + } + + @Test + void beforeKafkaListenerContainerFactoryTest() throws Exception { + withEnvironmentVariable("JAAS_CONFIG", "jaas_config") + .and("BOOTSTRAP_SERVERS", "localhost:9092") + .execute(() -> { + this.kafkaListenerContainerFactoryTest(); + }); + } + + public void kafkaListenerContainerFactoryTest() throws Exception { + JsonObject cbsConfigJsonForAutoCommitDisabled = new Gson().fromJson( + new String(Files.readAllBytes( + Paths.get(getSystemResource("autoCommitDisabledConfigurationFromCbs2.json").toURI()))), + JsonObject.class); + cbsConfigurationForAutoCommitDisabledMode.parseCBSConfig(cbsConfigJsonForAutoCommitDisabled); + kafkaConfig.kafkaListenerContainerFactory(cbsConfigurationForAutoCommitDisabledMode); + } +} diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/controllers/AppInfoControllerTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/controllers/AppInfoControllerTest.java index 1dba66a1..40b42480 100644 --- a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/controllers/AppInfoControllerTest.java +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/controllers/AppInfoControllerTest.java @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -21,19 +22,28 @@ package org.onap.dcaegen2.services.prh.controllers; import org.junit.jupiter.api.Test; +import org.onap.dcaegen2.services.prh.configuration.CbsConfigurationForAutoCommitDisabledMode; +import org.onap.dcaegen2.services.prh.configuration.KafkaConfig; import org.onap.dcaegen2.services.prh.configuration.PrhAppConfig; +import org.onap.dcaegen2.services.prh.tasks.DmaapConsumerTaskImpl; +import org.onap.dcaegen2.services.prh.tasks.ScheduledTasks; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Profile; import org.springframework.core.io.ByteArrayResource; import org.springframework.http.MediaType; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.IfProfileValue; +import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.reactive.server.WebTestClient; - import static org.mockito.Mockito.when; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @DirtiesContext +@ActiveProfiles(value = "prod") class AppInfoControllerTest { private static final String SAMPLE_GIT_INFO_CONTENT = "{ \"git.commit.id\" : \"37444e\" }"; @@ -44,17 +54,15 @@ class AppInfoControllerTest { @Autowired private WebTestClient webTestClient; + @MockBean + private ScheduledTasks scheduledTasks; + @Test void shouldProvideHeartbeatResponse() { - webTestClient - .get().uri("/heartbeat") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .expectStatus().isOk() + webTestClient.get().uri("/heartbeat").accept(MediaType.TEXT_PLAIN).exchange().expectStatus().isOk() .expectBody(String.class).isEqualTo("alive"); } - @Test void shouldProvideVersionInfo() { when(prhAppConfig.getGitInfo()).thenReturn(new ByteArrayResource(SAMPLE_GIT_INFO_CONTENT.getBytes())); @@ -66,4 +74,4 @@ class AppInfoControllerTest { .expectStatus().isOk() .expectBody(String.class).isEqualTo(SAMPLE_GIT_INFO_CONTENT); } -}
\ No newline at end of file +} diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/controllers/ScheduleControllerForAutoCommitDisabledTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/controllers/ScheduleControllerForAutoCommitDisabledTest.java new file mode 100644 index 00000000..43dcadf9 --- /dev/null +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/controllers/ScheduleControllerForAutoCommitDisabledTest.java @@ -0,0 +1,96 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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.controllers; + +import org.junit.Ignore; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.onap.dcaegen2.services.prh.configuration.KafkaConfig; +import org.onap.dcaegen2.services.prh.tasks.commit.KafkaConsumerTaskImpl; +import org.onap.dcaegen2.services.prh.tasks.commit.ScheduledTasksRunnerWithCommit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpStatus; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.reactive.server.WebTestClient; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) +@ActiveProfiles(value = "autoCommitDisabled") +class ScheduleControllerForAutoCommitDisabledTest { + + @MockBean + private ScheduledTasksRunnerWithCommit scheduledTasksRunnerWithCommit; + + @MockBean + private KafkaConfig kafkaConfig; + + @MockBean + private ConsumerFactory<String, String> consumerFactory; + + @MockBean + private ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory; + + @MockBean + private KafkaConsumerTaskImpl kafkaConsumerTaskImpl; + + @Autowired + private WebTestClient webTestClient; + + + @Test + void startEndpointShouldAllowStartingPrhTasks() { + when(scheduledTasksRunnerWithCommit.tryToStartTaskWithCommit()).thenReturn(true); + webTestClient + .get().uri("/start") + .exchange() + .expectStatus().isCreated() + .expectBody(String.class).isEqualTo("PRH Service has been started!"); + } + + @Test + void whenPrhTasksAreAlreadyStarted_shouldRespondThatRequestWasNotAccepted() { + when(scheduledTasksRunnerWithCommit.tryToStartTaskWithCommit()).thenReturn(false); + webTestClient + .get().uri("/start") + .exchange() + .expectStatus().isEqualTo(HttpStatus.NOT_ACCEPTABLE) + .expectBody(String.class).isEqualTo("PRH Service is already running!"); + } + + @Test + void stopEndpointShouldAllowStoppingPrhTasks() { + webTestClient + .get().uri("/stopPrh") + .exchange() + .expectStatus().isOk() + .expectBody(String.class).isEqualTo("PRH Service has been stopped!"); + + verify(scheduledTasksRunnerWithCommit).cancelTasks(); + } +} diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/controllers/ScheduleControllerTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/controllers/ScheduleControllerTest.java index ebdec09e..92a527b7 100644 --- a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/controllers/ScheduleControllerTest.java +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/controllers/ScheduleControllerTest.java @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -22,18 +23,21 @@ package org.onap.dcaegen2.services.prh.controllers; import org.junit.jupiter.api.Test; import org.onap.dcaegen2.services.prh.tasks.ScheduledTasksRunner; +import org.onap.dcaegen2.services.prh.tasks.commit.ScheduledTasksRunnerWithCommit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.HttpStatus; import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.IfProfileValue; +import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.reactive.server.WebTestClient; - import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @DirtiesContext +@ActiveProfiles("prod") class ScheduleControllerTest { @MockBean @@ -42,7 +46,7 @@ class ScheduleControllerTest { @Autowired private WebTestClient webTestClient; - @Test + @Test void startEndpointShouldAllowStartingPrhTasks() { when(scheduledTasksRunner.tryToStartTask()).thenReturn(true); webTestClient @@ -72,4 +76,4 @@ class ScheduleControllerTest { verify(scheduledTasksRunner).cancelTasks(); } -}
\ No newline at end of file +} diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/integration/PrhWorkflowIntegrationForAutoCommitDisabledTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/integration/PrhWorkflowIntegrationForAutoCommitDisabledTest.java new file mode 100644 index 00000000..21f9d099 --- /dev/null +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/integration/PrhWorkflowIntegrationForAutoCommitDisabledTest.java @@ -0,0 +1,225 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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.integration; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.github.tomakehurst.wiremock.client.WireMock; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import com.jayway.jsonpath.JsonPath; + +import io.vavr.collection.List; +import reactor.core.publisher.Flux; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.onap.dcaegen2.services.prh.MainApp; +import org.onap.dcaegen2.services.prh.adapter.aai.api.ConsumerDmaapModel; +import org.onap.dcaegen2.services.prh.adapter.kafka.ImmutableKafkaConfiguration; +import org.onap.dcaegen2.services.prh.adapter.kafka.KafkaConfiguration; +import org.onap.dcaegen2.services.prh.configuration.CbsConfiguration; +import org.onap.dcaegen2.services.prh.configuration.CbsConfigurationForAutoCommitDisabledMode; +import org.onap.dcaegen2.services.prh.service.DmaapConsumerJsonParser; +import org.onap.dcaegen2.services.prh.tasks.commit.KafkaConsumerTaskImpl; +import org.onap.dcaegen2.services.prh.tasks.commit.ScheduledTasksRunnerWithCommit; +import org.onap.dcaegen2.services.prh.tasks.commit.ScheduledTasksWithCommit; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.api.MessageRouterPublisher; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.ImmutableMessageRouterPublishResponse; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRouterPublishRequest; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRouterPublishResponse; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRouterSubscribeRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.configurationprocessor.json.JSONException; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ActiveProfiles; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; +import static com.github.tomakehurst.wiremock.client.WireMock.ok; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.anyRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.verify; +import static com.github.tomakehurst.wiremock.client.WireMock.patch; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import static java.lang.ClassLoader.getSystemResource; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * * @author <a href="mailto:PRANIT.KAPDULE@t-systems.com">Pranit Kapdule</a> on + * * 24/08/23 + * */ + +@SpringBootTest +@AutoConfigureWireMock(port = 0) +@ActiveProfiles(value = "autoCommitDisabled") +class PrhWorkflowIntegrationForAutoCommitDisabledTest { + + @Autowired + private ScheduledTasksWithCommit scheduledTasksWithCommit; + + @MockBean + private ScheduledTasksRunnerWithCommit scheduledTasksRunnerWithCommit; // just to disable scheduling - some + // configurability in ScheduledTaskRunner not + // to start tasks at app startup would be + // welcome + + @MockBean + private KafkaConsumerTaskImpl kafkaConsumerTaskImpl; + + @Autowired + private DmaapConsumerJsonParser dmaapConsumerJsonParser; + + @SpyBean + CbsConfiguration cbsConfiguration; + + @Mock + MessageRouterPublisher publisher; + + @Configuration + @Import(MainApp.class) + static class CbsConfigTestConfig { + + @Value("http://localhost:${wiremock.server.port}") + private String wiremockServerAddress; + + protected KafkaConfiguration kafkaConfiguration; + + @Bean + public CbsConfigurationForAutoCommitDisabledMode cbsConfigurationForAutoCommitDisabledMode() { + + JsonObject cbsConfigJson = new Gson() + .fromJson(getResourceContent("autoCommitDisabledConfigurationFromCbs2.json") + .replaceAll("https?://dmaap-mr[\\w.]*:\\d+", wiremockServerAddress) + .replaceAll("https?://aai[\\w.]*:\\d+", wiremockServerAddress), JsonObject.class); + + CbsConfigurationForAutoCommitDisabledMode cbsConfigurationForAutoCommitDisabledMode = new CbsConfigurationForAutoCommitDisabledMode(); + + try { + withEnvironmentVariable("JAAS_CONFIG", "jaas_config") + .and("BOOTSTRAP_SERVERS", "localhost:9092") + .execute(() -> { + cbsConfigurationForAutoCommitDisabledMode.parseCBSConfig(cbsConfigJson); + }); + + } catch (Exception e) { + //Exception is expected as environment variable for JAAS_CONFIG is not available + if (e.getMessage() == "kafkaJaasConfig") { + kafkaConfiguration = new ImmutableKafkaConfiguration.Builder().kafkaBoostrapServerConfig("0.0.0.0") + .groupIdConfig("CG1").kafkaSaslMechanism("SASL_MECHANISM") + .kafkaSecurityProtocol("SEC-PROTOCOL").kafkaJaasConfig("JAAS_CONFIG").build(); + cbsConfigurationForAutoCommitDisabledMode.setKafkaConfiguration(kafkaConfiguration); + + } + + } + return cbsConfigurationForAutoCommitDisabledMode; + }; + + } + + @BeforeEach + void resetWireMock() { + WireMock.reset(); + } + + @Test + void beforeCbsConfigurationForAutoCommitDisabledMode() throws Exception { + withEnvironmentVariable("JAAS_CONFIG", "jaas_config") + .execute(() -> { + this.whenThereAreNoEventsInDmaap_WorkflowShouldFinish(); + }); + } + + void whenThereAreNoEventsInDmaap_WorkflowShouldFinish() throws JSONException { + + when(kafkaConsumerTaskImpl.execute()).thenReturn(Flux.empty()); + + scheduledTasksWithCommit.scheduleKafkaPrhEventTask(); + + verify(0, anyRequestedFor(urlPathMatching("/aai.*"))); + verify(0, postRequestedFor(urlPathMatching("/events.*"))); + } + + @Test + void beforeWhenThereIsAnEventsInDmaap_ShouldSendPnfReadyNotification() throws Exception { + withEnvironmentVariable("JAAS_CONFIG", "jaas_config") + .execute(() -> { + this.whenThereIsAnEventsInDmaap_ShouldSendPnfReadyNotification(); + }); + } + + void whenThereIsAnEventsInDmaap_ShouldSendPnfReadyNotification() + throws JSONException, JsonMappingException, JsonProcessingException { + + String event = getResourceContent("integration/event.json"); + String pnfName = JsonPath.read(event, "$.event.commonEventHeader.sourceName"); + + java.util.List<String> eventList = new ArrayList<>(); + eventList.add(event); + + Flux<ConsumerDmaapModel> fluxList = dmaapConsumerJsonParser + .getConsumerDmaapModelFromKafkaConsumerRecord(eventList); + + stubFor(get(urlEqualTo("/aai/v23/network/pnfs/pnf/" + pnfName)).willReturn(ok().withBody("{}"))); + stubFor(patch(urlEqualTo("/aai/v23/network/pnfs/pnf/" + pnfName))); + stubFor(post(urlEqualTo("/events/unauthenticated.PNF_READY"))); + + when(kafkaConsumerTaskImpl.execute()).thenReturn(fluxList); + + List<String> expectedItems = List.of(event); + Flux<MessageRouterPublishResponse> pubresp = Flux.just(ImmutableMessageRouterPublishResponse + .builder() + .items(expectedItems.map(JsonPrimitive::new)) + .build()); + when(cbsConfiguration.getMessageRouterPublisher()).thenReturn(publisher); + when(publisher.put(any(MessageRouterPublishRequest.class),any())).thenReturn(pubresp); + scheduledTasksWithCommit.scheduleKafkaPrhEventTask(); + verify(publisher,times(1)).put(any(MessageRouterPublishRequest.class),any()); + + } + + private static String getResourceContent(String resourceName) { + try { + return new String(Files.readAllBytes(Paths.get(getSystemResource(resourceName).toURI()))); + } catch (Exception e) { + throw new RuntimeException("failed loading content of '" + resourceName + "'", e); + } + } +} diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/integration/PrhWorkflowIntegrationTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/integration/PrhWorkflowIntegrationTest.java index 01beb88b..a77fcd75 100644 --- a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/integration/PrhWorkflowIntegrationTest.java +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/integration/PrhWorkflowIntegrationTest.java @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2019-2021 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -23,59 +24,107 @@ package org.onap.dcaegen2.services.prh.integration; import com.github.tomakehurst.wiremock.client.WireMock; import com.google.gson.Gson; import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; import com.jayway.jsonpath.JsonPath; + +import io.vavr.collection.List; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.Mock; import org.onap.dcaegen2.services.prh.MainApp; import org.onap.dcaegen2.services.prh.configuration.CbsConfiguration; import org.onap.dcaegen2.services.prh.tasks.ScheduledTasks; import org.onap.dcaegen2.services.prh.tasks.ScheduledTasksRunner; +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.ImmutableMessageRouterPublishResponse; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.ImmutableMessageRouterSubscribeResponse; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRouterPublishRequest; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRouterPublishResponse; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRouterSubscribeRequest; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRouterSubscribeResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; - +import org.springframework.test.context.ActiveProfiles; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; +import static com.github.tomakehurst.wiremock.client.WireMock.ok; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.anyRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.verify; +import static com.github.tomakehurst.wiremock.client.WireMock.patch; import java.nio.file.Files; import java.nio.file.Paths; - -import static com.github.tomakehurst.wiremock.client.WireMock.*; import static java.lang.ClassLoader.getSystemResource; import static java.util.Collections.singletonList; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; @SpringBootTest @AutoConfigureWireMock(port = 0) +@ActiveProfiles(value = "prod") class PrhWorkflowIntegrationTest { @Autowired private ScheduledTasks scheduledTasks; - + + @SpyBean + CbsConfiguration cbsConfiguration; + @MockBean private ScheduledTasksRunner scheduledTasksRunner; // just to disable scheduling - some configurability in ScheduledTaskRunner not to start tasks at app startup would be welcome - - + + @Mock + MessageRouterSubscriber subscriber; + + @Mock + MessageRouterPublisher publisher; + @Configuration @Import(MainApp.class) static class CbsConfigTestConfig { @Value("http://localhost:${wiremock.server.port}") private String wiremockServerAddress; - + @Bean - public CbsConfiguration cbsConfiguration() { + public CbsConfiguration cbsConfiguration() throws Exception { JsonObject cbsConfigJson = new Gson().fromJson(getResourceContent("configurationFromCbs.json") .replaceAll("https?://dmaap-mr[\\w.]*:\\d+", wiremockServerAddress) .replaceAll("https?://aai[\\w.]*:\\d+", wiremockServerAddress), JsonObject.class); - + CbsConfiguration cbsConfiguration = new CbsConfiguration(); - cbsConfiguration.parseCBSConfig(cbsConfigJson); + withEnvironmentVariable("JAAS_CONFIG", "jaas_config") + .and("BOOTSTRAP_SERVERS", "localhost:9092") + .execute(() -> { + cbsConfiguration.parseCBSConfig(cbsConfigJson); + }); + return cbsConfiguration; } + + } @BeforeEach @@ -85,7 +134,7 @@ class PrhWorkflowIntegrationTest { @Test - void whenThereAreNoEventsInDmaap_WorkflowShouldFinish() { + void whenThereAreNoEventsInDmaap_WorkflowShouldFinish() { stubFor(get(urlEqualTo("/events/unauthenticated.VES_PNFREG_OUTPUT/OpenDCAE-c12/c12")) .willReturn(aResponse().withBody("[]"))); @@ -100,17 +149,27 @@ class PrhWorkflowIntegrationTest { void whenThereIsAnEventsInDmaap_ShouldSendPnfReadyNotification() { String event = getResourceContent("integration/event.json"); String pnfName = JsonPath.read(event, "$.event.commonEventHeader.sourceName"); - - stubFor(get(urlEqualTo("/events/unauthenticated.VES_PNFREG_OUTPUT/OpenDCAE-c12/c12")) - .willReturn(ok().withBody(new Gson().toJson(singletonList(event))))); stubFor(get(urlEqualTo("/aai/v23/network/pnfs/pnf/" + pnfName)).willReturn(ok().withBody("{}"))); stubFor(patch(urlEqualTo("/aai/v23/network/pnfs/pnf/" + pnfName))); - stubFor(post(urlEqualTo("/events/unauthenticated.PNF_READY"))); - + + List<String> expectedItems = List.of(event); + Mono<MessageRouterSubscribeResponse> resp = Mono.just(ImmutableMessageRouterSubscribeResponse + .builder() + .items(expectedItems.map(JsonPrimitive::new)) + .build()); + Flux<MessageRouterPublishResponse> pubresp = Flux.just(ImmutableMessageRouterPublishResponse + .builder() + .items(expectedItems.map(JsonPrimitive::new)) + .build()); + + when(cbsConfiguration.getMessageRouterSubscriber()).thenReturn(subscriber); + when(cbsConfiguration.getMessageRouterPublisher()).thenReturn(publisher); + when(subscriber.get(any(MessageRouterSubscribeRequest.class))).thenReturn(resp); + when(publisher.put(any(MessageRouterPublishRequest.class),any())).thenReturn(pubresp); + scheduledTasks.scheduleMainPrhEventTask(); - - verify(1, postRequestedFor(urlEqualTo("/events/unauthenticated.PNF_READY")) - .withRequestBody(matchingJsonPath("$[0].correlationId", equalTo(pnfName)))); + verify(subscriber,times(1)).get(any(MessageRouterSubscribeRequest.class)); + verify(publisher,times(1)).put(any(MessageRouterPublishRequest.class),any()); } diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/integration/PrhWorkflowSchedulingIntegrationForAutoCommitDisabledTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/integration/PrhWorkflowSchedulingIntegrationForAutoCommitDisabledTest.java new file mode 100644 index 00000000..a623e24c --- /dev/null +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/integration/PrhWorkflowSchedulingIntegrationForAutoCommitDisabledTest.java @@ -0,0 +1,100 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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.integration; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.mockito.stubbing.Answer; +import org.onap.dcaegen2.services.prh.configuration.KafkaConfig; +import org.onap.dcaegen2.services.prh.tasks.commit.KafkaConsumerTask; +import org.onap.dcaegen2.services.prh.tasks.commit.ScheduledTasksRunnerWithCommit; +import org.onap.dcaegen2.services.prh.tasks.commit.ScheduledTasksWithCommit; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.doAnswer; + + +@SpringBootTest +@TestPropertySource (properties = {"prh.workflow-scheduling-interval=20ms","spring.main.allow-bean-definition-overriding=true"}) +@DirtiesContext +@ActiveProfiles(value = "autoCommitDisabled") +@Disabled +class PrhWorkflowSchedulingIntegrationForAutoCommitDisabledTest { + + private static final int EXPECTED_INVOCATIONS_NUMBER = 1; + private static final int REMAINING_INVOCATIONS_NUMBER = 0; + + @MockBean + private ScheduledTasksRunnerWithCommit scheduledTasksRunnerWithCommit; + + @MockBean + private ScheduledTasksWithCommit scheduledTasksWithCommit; + + @MockBean + private KafkaConsumerTask kafkaConsumerTask; + + + @MockBean + private KafkaConfig kafkaConfig; + + @MockBean + private ConsumerFactory<String, String> consumerFactory; + + @MockBean + private ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory; + + private CountDownLatch invocationLatch; + + @Test + void prhWorkflowShouldBeExecutedRightAfterApplicationStart() { + try { + + invocationLatch = new CountDownLatch(EXPECTED_INVOCATIONS_NUMBER); + doAnswer(registerInvocation(invocationLatch)).when(scheduledTasksWithCommit).scheduleKafkaPrhEventTask(); + assertThatMethodWasInvokedOnce(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void assertThatMethodWasInvokedOnce() throws InterruptedException { + boolean awaitResult = invocationLatch.await(1, TimeUnit.SECONDS); + System.out.println("###awaitResult="+awaitResult); + assertEquals(REMAINING_INVOCATIONS_NUMBER, invocationLatch.getCount()); + } + + private static Answer registerInvocation(CountDownLatch invocationLatch) { + return invocation -> { + System.out.println("###before countDown:"+invocationLatch.getCount()); + invocationLatch.countDown(); + System.out.println("###after countDown:"+invocationLatch.getCount()); + return null; + }; + } +} diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/integration/PrhWorkflowSchedulingIntegrationTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/integration/PrhWorkflowSchedulingIntegrationTest.java index 939dd2a3..8fb952d0 100644 --- a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/integration/PrhWorkflowSchedulingIntegrationTest.java +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/integration/PrhWorkflowSchedulingIntegrationTest.java @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -27,14 +28,17 @@ import org.mockito.stubbing.Answer; import org.onap.dcaegen2.services.prh.tasks.ScheduledTasks; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.doAnswer; @SpringBootTest @TestPropertySource (properties = {"prh.workflow-scheduling-interval=20ms"}) +@ActiveProfiles(value = "prod") +@DirtiesContext class PrhWorkflowSchedulingIntegrationTest { private static final int EXPECTED_INVOCATIONS_NUMBER = 1; @@ -61,4 +65,4 @@ class PrhWorkflowSchedulingIntegrationTest { return null; }; } -}
\ No newline at end of file +} diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/service/DmaapConsumerJsonParserTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/service/DmaapConsumerJsonParserTest.java index 9dab7aaa..ba759354 100644 --- a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/service/DmaapConsumerJsonParserTest.java +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/service/DmaapConsumerJsonParserTest.java @@ -3,6 +3,7 @@ * PNF-REGISTRATION-HANDLER * ================================================================================ * Copyright (C) 2018 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -20,16 +21,12 @@ package org.onap.dcaegen2.services.prh.service; -import static org.mockito.Mockito.spy; - import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import io.vavr.collection.List; -import java.util.Optional; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.onap.dcaegen2.services.prh.adapter.aai.api.ConsumerDmaapModel; import org.onap.dcaegen2.services.prh.adapter.aai.api.ImmutableConsumerDmaapModel; import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.ImmutableMessageRouterSubscribeResponse; @@ -37,6 +34,11 @@ import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRo import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import java.util.Optional; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + /** * @author <a href="mailto:przemyslaw.wasala@nokia.com">Przemysław Wąsala</a> on 5/8/18 */ @@ -108,7 +110,7 @@ class DmaapConsumerJsonParserTest { //when DmaapConsumerJsonParser dmaapConsumerJsonParser = spy(new DmaapConsumerJsonParser()); JsonElement jsonElement = jsonParser.parse(parsed); - Mockito.doReturn(Optional.of(jsonElement.getAsJsonObject())) + doReturn(Optional.of(jsonElement.getAsJsonObject())) .when(dmaapConsumerJsonParser).getJsonObjectFromAnArray(jsonElement); ConsumerDmaapModel consumerDmaapModel = dmaapConsumerJsonParser @@ -171,7 +173,7 @@ class DmaapConsumerJsonParserTest { //when DmaapConsumerJsonParser dmaapConsumerJsonParser = spy(new DmaapConsumerJsonParser()); JsonElement jsonElement = new JsonParser().parse(parsed); - Mockito.doReturn(Optional.of(jsonElement.getAsJsonObject())) + doReturn(Optional.of(jsonElement.getAsJsonObject())) .when(dmaapConsumerJsonParser).getJsonObjectFromAnArray(jsonElement); ConsumerDmaapModel consumerDmaapModel = dmaapConsumerJsonParser .getJsonObject(Mono.just((response))).blockFirst(); @@ -238,7 +240,7 @@ class DmaapConsumerJsonParserTest { //when DmaapConsumerJsonParser dmaapConsumerJsonParser = spy(new DmaapConsumerJsonParser()); JsonElement jsonElement = jsonParser.parse(parsed); - Mockito.doReturn(Optional.of(jsonElement.getAsJsonObject())) + doReturn(Optional.of(jsonElement.getAsJsonObject())) .when(dmaapConsumerJsonParser).getJsonObjectFromAnArray(jsonElement); ConsumerDmaapModel consumerDmaapModel = dmaapConsumerJsonParser @@ -302,7 +304,7 @@ class DmaapConsumerJsonParserTest { //when DmaapConsumerJsonParser dmaapConsumerJsonParser = spy(new DmaapConsumerJsonParser()); JsonElement jsonElement = jsonParser.parse(parsed); - Mockito.doReturn(Optional.of(jsonElement.getAsJsonObject())) + doReturn(Optional.of(jsonElement.getAsJsonObject())) .when(dmaapConsumerJsonParser).getJsonObjectFromAnArray(jsonElement); ConsumerDmaapModel consumerDmaapModel = dmaapConsumerJsonParser @@ -334,7 +336,7 @@ class DmaapConsumerJsonParserTest { DmaapConsumerJsonParser dmaapConsumerJsonParser = spy(new DmaapConsumerJsonParser()); JsonElement jsonElement = jsonParser.parse(parsed); - Mockito.doReturn(Optional.of(jsonElement.getAsJsonObject())) + doReturn(Optional.of(jsonElement.getAsJsonObject())) .when(dmaapConsumerJsonParser).getJsonObjectFromAnArray(jsonElement); String incorrectMessage = "{\"event\": {" + "\"commonEventHeader\": {}," @@ -380,7 +382,7 @@ class DmaapConsumerJsonParserTest { DmaapConsumerJsonParser dmaapConsumerJsonParser = spy(new DmaapConsumerJsonParser()); JsonElement jsonElement = jsonParser.parse(parsed); - Mockito.doReturn(Optional.of(jsonElement.getAsJsonObject())) + doReturn(Optional.of(jsonElement.getAsJsonObject())) .when(dmaapConsumerJsonParser).getJsonObjectFromAnArray(jsonElement); String jsonWithoutSourceName = "{\"event\": {" @@ -430,7 +432,7 @@ class DmaapConsumerJsonParserTest { DmaapConsumerJsonParser dmaapConsumerJsonParser = spy(new DmaapConsumerJsonParser()); JsonElement jsonElement = jsonParser.parse(parsed); - Mockito.doReturn(Optional.of(jsonElement.getAsJsonObject())) + doReturn(Optional.of(jsonElement.getAsJsonObject())) .when(dmaapConsumerJsonParser).getJsonObjectFromAnArray(jsonElement); String jsonWithoutIpInformation = "{\"event\": {" @@ -497,7 +499,7 @@ class DmaapConsumerJsonParserTest { //when DmaapConsumerJsonParser dmaapConsumerJsonParser = spy(new DmaapConsumerJsonParser()); JsonElement jsonElement = jsonParser.parse(parsed); - Mockito.doReturn(Optional.of(jsonElement.getAsJsonObject())) + doReturn(Optional.of(jsonElement.getAsJsonObject())) .when(dmaapConsumerJsonParser).getJsonObjectFromAnArray(jsonElement); dmaapConsumerJsonParser.getJsonObject(Mono.just((response))); @@ -573,7 +575,7 @@ class DmaapConsumerJsonParserTest { //when DmaapConsumerJsonParser dmaapConsumerJsonParser = spy(new DmaapConsumerJsonParser()); JsonElement jsonElement = jsonParser.parse(parsed); - Mockito.doReturn(Optional.of(jsonElement.getAsJsonObject())) + doReturn(Optional.of(jsonElement.getAsJsonObject())) .when(dmaapConsumerJsonParser).getJsonObjectFromAnArray(jsonElement); ConsumerDmaapModel consumerDmaapModel = dmaapConsumerJsonParser.getJsonObject(Mono.just(response)) .blockFirst(); diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTaskImplTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTaskImplTest.java index e81b3746..517fe73a 100644 --- a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTaskImplTest.java +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTaskImplTest.java @@ -3,6 +3,7 @@ * PROJECT * ================================================================================ * Copyright (C) 2018 NOKIA Intellectual Property. All rights reserved. + * Copyright (C) 2023 Deutsche Telekom 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. @@ -26,6 +27,8 @@ import static org.mockito.Mockito.mock; import java.util.Collections; import java.util.List; + + import org.assertj.core.util.Lists; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -38,6 +41,7 @@ import org.onap.dcaegen2.services.prh.adapter.aai.api.AaiPnfResultModel; import org.onap.dcaegen2.services.prh.adapter.aai.api.AaiServiceInstanceQueryModel; import org.onap.dcaegen2.services.prh.adapter.aai.api.AaiServiceInstanceResultModel; import org.onap.dcaegen2.services.prh.adapter.aai.api.ConsumerDmaapModel; +import org.onap.dcaegen2.services.prh.adapter.aai.api.ImmutableConsumerDmaapModel; import org.onap.dcaegen2.services.prh.model.ImmutableRelationshipData; import org.onap.dcaegen2.services.prh.model.Relationship; import org.onap.dcaegen2.services.prh.model.RelationshipData; @@ -85,18 +89,6 @@ class AaiQueryTaskImplTest { } @Test - void whenPnfIsUnavailable_ShouldThrowException() { - //given - given(getPnfModelClient.getAaiResponse(aaiModel)).willReturn(Mono.error(new Exception("404"))); - - //when - final Mono<Boolean> task = sut.execute(aaiModel); - - //then - Assertions.assertThrows(Exception.class, task::block); - } - - @Test void whenPnfIsAvailableButRelationshipIsNull_ShouldReturnFalse() { //given given(pnfResultModel.getRelationshipList()).willReturn(null); @@ -203,4 +195,12 @@ class AaiQueryTaskImplTest { private void configurePnfClient(final ConsumerDmaapModel aaiModel, final AaiPnfResultModel pnfResultModel) { given(getPnfModelClient.getAaiResponse(aaiModel)).willReturn(Mono.just(pnfResultModel)); } + + @Test + void testFindPnfInAAIActive(){ + ConsumerDmaapModel model = ImmutableConsumerDmaapModel.builder().correlationId("123").build(); + configurePnfClient(model, pnfResultModel); + Mono<ConsumerDmaapModel> test = sut.findPnfinAAI(model); + Assertions.assertNotNull(test); + } } diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/commit/EpochDateTimeConversionTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/commit/EpochDateTimeConversionTest.java new file mode 100644 index 00000000..850587e0 --- /dev/null +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/commit/EpochDateTimeConversionTest.java @@ -0,0 +1,52 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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.tasks.commit; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class EpochDateTimeConversionTest { + + private EpochDateTimeConversion epochDateTimeConversion; + + @BeforeEach + void setUp() { + epochDateTimeConversion = new EpochDateTimeConversion(); + epochDateTimeConversion.setDaysForRecords("3"); + } + + @Test + public void getStartDateOfTheDayTest(){ + epochDateTimeConversion.getDaysForRecords(); + Long day = epochDateTimeConversion.getStartDateOfTheDay(); + Assertions.assertNotNull(day); + } + + @Test + public void getEndDateOfTheDayTest(){ + Long day = epochDateTimeConversion.getEndDateOfTheDay(); + Assertions.assertNotNull(day); + } +} diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/commit/KafkaConsumerTaskImplTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/commit/KafkaConsumerTaskImplTest.java new file mode 100644 index 00000000..42a2e7f4 --- /dev/null +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/commit/KafkaConsumerTaskImplTest.java @@ -0,0 +1,151 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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.tasks.commit; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.common.header.Headers; +import org.apache.kafka.common.header.internals.RecordHeaders; +import org.apache.kafka.common.record.TimestampType; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.onap.dcaegen2.services.prh.adapter.aai.api.ConsumerDmaapModel; +import org.onap.dcaegen2.services.prh.configuration.CbsConfigurationForAutoCommitDisabledMode; +import org.onap.dcaegen2.services.prh.service.DmaapConsumerJsonParser; +import org.springframework.kafka.support.Acknowledgment; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; +import reactor.core.publisher.Flux; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable; +import static java.lang.ClassLoader.getSystemResource; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(MockitoExtension.class) +public class KafkaConsumerTaskImplTest { + + @Mock + private Acknowledgment acknowledgment; + + private KafkaConsumerTaskImpl kafkaConsumerTask; + + private DmaapConsumerJsonParser dmaapConsumerJsonParser; + + private EpochDateTimeConversion epochDateTimeConversion; + + private CbsConfigurationForAutoCommitDisabledMode cbsConfigurationForAutoCommitDisabled; + + private JsonObject cbsConfigJsonForAutoCommitDisabled; + + @BeforeEach + void beforeEach() throws JsonSyntaxException, IOException, URISyntaxException { + cbsConfigJsonForAutoCommitDisabled = new Gson().fromJson( + new String(Files.readAllBytes( + Paths.get(getSystemResource("autoCommitDisabledConfigurationFromCbs2.json").toURI()))), + JsonObject.class); + cbsConfigurationForAutoCommitDisabled = new CbsConfigurationForAutoCommitDisabledMode(); + dmaapConsumerJsonParser = new DmaapConsumerJsonParser(); + epochDateTimeConversion = new EpochDateTimeConversion(); + + } + + @Test + void beforeOnMessageTest() throws Exception { + withEnvironmentVariable("JAAS_CONFIG", "jaas_config") + .and("BOOTSTRAP_SERVERS", "localhost:9092") + .execute(() -> { + cbsConfigurationForAutoCommitDisabled.parseCBSConfig(cbsConfigJsonForAutoCommitDisabled); + kafkaConsumerTask = new KafkaConsumerTaskImpl(cbsConfigurationForAutoCommitDisabled, + dmaapConsumerJsonParser, epochDateTimeConversion); + List<ConsumerRecord<String, String>> list = new ArrayList<>(); + TimestampType timestampType = null; + Headers headers = new RecordHeaders(); + epochDateTimeConversion.setDaysForRecords("3"); + ConsumerRecord<String, String> records = new ConsumerRecord<>("test-topic", 1, 1l, 0l, timestampType, 1, 1, + "test-key", "test-value", headers, null); + list.add(records); + kafkaConsumerTask.onMessage(list, acknowledgment); + String actualTopicInList = list.get(0).topic(); + String expectedTopicInList = "test-topic"; + assertEquals(expectedTopicInList, actualTopicInList, "topic is not matching"); + assertThat(kafkaConsumerTask.getOffset().equals(acknowledgment)); + assertThat(kafkaConsumerTask.getJsonEvent().contains("test-topic")); + }); + } + + @Test + void beforeCommitOffsetTest() throws Exception { + withEnvironmentVariable("JAAS_CONFIG", "jaas_config") + .and("BOOTSTRAP_SERVERS", "localhost:9092") + .execute(() -> { + cbsConfigurationForAutoCommitDisabled.parseCBSConfig(cbsConfigJsonForAutoCommitDisabled); + kafkaConsumerTask = new KafkaConsumerTaskImpl(cbsConfigurationForAutoCommitDisabled, + dmaapConsumerJsonParser, epochDateTimeConversion); + kafkaConsumerTask.commitOffset(); + }); + } + + @Test + void beforeExecuteTest() throws Exception { + withEnvironmentVariable("JAAS_CONFIG", "jaas_config") + .and("BOOTSTRAP_SERVERS", "localhost:9092") + .execute(() -> { + cbsConfigurationForAutoCommitDisabled.parseCBSConfig(cbsConfigJsonForAutoCommitDisabled); + kafkaConsumerTask = new KafkaConsumerTaskImpl(cbsConfigurationForAutoCommitDisabled, + dmaapConsumerJsonParser, epochDateTimeConversion); + String event = getResourceContent("integration/event.json"); + java.util.List<String> eventList = new ArrayList<>(); + eventList.add(event); + kafkaConsumerTask.setJsonEvent(eventList); + Flux<ConsumerDmaapModel> flux = kafkaConsumerTask.execute(); + String expectedSourceName = "NOK6061ZW8"; + String actualSourceName = flux.blockFirst().getCorrelationId(); + + String expectedOamV4IpAddress = "val3"; + String actualOamV4IpAddress = flux.blockFirst().getIpv4(); + + String expectedOamV6IpAddress = "val4"; + String actualOamV6IpAddress = flux.blockFirst().getIpv6(); + + assertEquals(expectedSourceName, actualSourceName, "SourceName is not matching"); + assertEquals(expectedOamV4IpAddress, actualOamV4IpAddress, "OamV4IpAddress is not matching"); + assertEquals(expectedOamV6IpAddress, actualOamV6IpAddress, "OamV6IpAddress is not matching"); + }); + } + + private static String getResourceContent(String resourceName) { + try { + return new String(Files.readAllBytes(Paths.get(getSystemResource(resourceName).toURI()))); + } catch (Exception e) { + throw new RuntimeException("failed loading content of '" + resourceName + "'", e); + } + } + +} diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/commit/ScheduledTasksRunnerWithCommitTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/commit/ScheduledTasksRunnerWithCommitTest.java new file mode 100644 index 00000000..401e351f --- /dev/null +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/commit/ScheduledTasksRunnerWithCommitTest.java @@ -0,0 +1,72 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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.tasks.commit; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.onap.dcaegen2.services.prh.configuration.PrhProperties; +import org.springframework.boot.context.event.ApplicationStartedEvent; +import org.springframework.scheduling.TaskScheduler; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@ExtendWith(MockitoExtension.class) +public class ScheduledTasksRunnerWithCommitTest { + + @Mock + private ScheduledTasksWithCommit scheduledTasksWithCommit; + + @Mock + private TaskScheduler taskScheduler; + + @Mock + private PrhProperties prhProperties; + + @Mock + private ApplicationStartedEvent applicationStartedEvent; + + private ScheduledTasksRunnerWithCommit scheduledTasksRunnerWithCommit; + + @BeforeEach + void setUp() { + scheduledTasksRunnerWithCommit = new ScheduledTasksRunnerWithCommit(taskScheduler, scheduledTasksWithCommit, prhProperties); + } + + @Test + void onApplicationStartedEvent() { + scheduledTasksRunnerWithCommit.onApplicationStartedEvent(applicationStartedEvent); + assertFalse(scheduledTasksRunnerWithCommit.tryToStartTaskWithCommit()); + } + + @Test + void cancelTasks() { + scheduledTasksRunnerWithCommit.cancelTasks(); + } + + @Test + void tryToStartTaskWithCommit() { + scheduledTasksRunnerWithCommit.tryToStartTaskWithCommit(); + assertFalse(scheduledTasksRunnerWithCommit.tryToStartTaskWithCommit()); + } +} diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/commit/ScheduledTasksWithCommitTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/commit/ScheduledTasksWithCommitTest.java new file mode 100644 index 00000000..64779027 --- /dev/null +++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/commit/ScheduledTasksWithCommitTest.java @@ -0,0 +1,263 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2023 Deutsche Telekom 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.tasks.commit; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import java.util.Collections; +import java.util.Map; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.onap.dcaegen2.services.prh.adapter.aai.api.ConsumerDmaapModel; +import org.onap.dcaegen2.services.prh.adapter.aai.api.ImmutableConsumerDmaapModel; +import org.onap.dcaegen2.services.prh.exceptions.DmaapEmptyResponseException; +import org.onap.dcaegen2.services.prh.exceptions.PrhTaskException; +import org.onap.dcaegen2.services.prh.tasks.AaiProducerTask; +import org.onap.dcaegen2.services.prh.tasks.AaiQueryTask; +import org.onap.dcaegen2.services.prh.tasks.BbsActionsTask; +import org.onap.dcaegen2.services.prh.tasks.DmaapPublisherTask; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.model.MessageRouterPublishResponse; +import org.springframework.boot.configurationprocessor.json.JSONException; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + + +@ExtendWith(MockitoExtension.class) +class ScheduledTasksWithCommitTest { + private final static ConsumerDmaapModel DMAAP_MODEL = + ImmutableConsumerDmaapModel + .builder() + .correlationId("SomeId") + .ipv4("ipv4") + .ipv6("ipv6") + .build(); + + @Mock + private DmaapPublisherTask readyPublisher; + + @Mock + private DmaapPublisherTask updatePublisher; + + + @Mock + private BbsActionsTask bbsActionsTask; + + @Mock + private KafkaConsumerTask kafkaConsumerTask; + + @Mock + private AaiQueryTask aaiQueryTask; + + @Mock + private AaiProducerTask aaiProducerTask; + + private final Map<String, String> context = Collections.emptyMap(); + + private ScheduledTasksWithCommit sut; + + @BeforeEach + void setUp() { + sut = new ScheduledTasksWithCommit( + kafkaConsumerTask, + readyPublisher, + updatePublisher, + aaiQueryTask, + aaiProducerTask, + bbsActionsTask, + context); + } + + @Test + void testQueryAAiForPNFOnSuccess() throws JSONException, PrhTaskException { + ScheduledTasksWithCommit.State state = new ScheduledTasksWithCommit.State(DMAAP_MODEL, false ); + MessageRouterPublishResponse messageRouterPublishResponse = new MessageRouterPublishResponse() { + @Override + public @Nullable String failReason() { + return null; + } + }; + when(kafkaConsumerTask.execute()).thenReturn(Flux.just(DMAAP_MODEL)); + when(aaiQueryTask.findPnfinAAI(DMAAP_MODEL)).thenReturn(Mono.just(DMAAP_MODEL)); + when(aaiQueryTask.execute(DMAAP_MODEL)).thenReturn(Mono.just(true)); + when(aaiProducerTask.execute(state.dmaapModel)).thenReturn(Mono.just(DMAAP_MODEL)); + when(updatePublisher.execute(state.dmaapModel)).thenReturn(Flux.just(messageRouterPublishResponse)); + + sut.scheduleKafkaPrhEventTask(); + + verifyIfLogicalLinkWasNotCreated(); + verifyThatPnfModelWasNotSentDmaapPnfReadyTopic(); + } + + @Test + void testQueryAAiForPNF() throws JSONException, PrhTaskException { + ScheduledTasksWithCommit.State state = new ScheduledTasksWithCommit.State(DMAAP_MODEL, true); + MessageRouterPublishResponse messageRouterPublishResponse = new MessageRouterPublishResponse() { + @Override + public @Nullable String failReason() { + return null; + } + }; + when(kafkaConsumerTask.execute()).thenReturn(Flux.just(DMAAP_MODEL)); + when(aaiQueryTask.findPnfinAAI(DMAAP_MODEL)).thenReturn(Mono.just(DMAAP_MODEL)); + when(aaiQueryTask.execute(DMAAP_MODEL)).thenReturn(Mono.just(true)); + when(aaiProducerTask.execute(state.dmaapModel)).thenReturn(Mono.just(DMAAP_MODEL)); + when(updatePublisher.execute(state.dmaapModel)).thenReturn(Flux.just(messageRouterPublishResponse)); + + sut.scheduleKafkaPrhEventTask(); + + verifyIfLogicalLinkWasNotCreated(); + verifyThatPnfModelWasNotSentDmaapPnfReadyTopic(); + } + + @Test + void testQueryAAiForPNFOnError() throws JSONException, PrhTaskException { + when(kafkaConsumerTask.execute()).thenReturn(Flux.just(DMAAP_MODEL)); + + sut.scheduleKafkaPrhEventTask(); + + verifyThatPnfUpdateWasNotSentToAai(); + + verifyIfLogicalLinkWasNotCreated(); + verifyThatPnfModelWasNotSentDmaapPnfReadyTopic(); + verifyThatPnfModelWasNotSentDmaapPnfUpdateTopic(); + } + + @Test + void testQueryAAiForPNFOnPRHException() throws JSONException, PrhTaskException { + ScheduledTasksWithCommit.State state = new ScheduledTasksWithCommit.State(DMAAP_MODEL, false ); + MessageRouterPublishResponse messageRouterPublishResponse = new MessageRouterPublishResponse() { + @Override + public @Nullable String failReason() { + return null; + } + }; + when(kafkaConsumerTask.execute()).thenReturn(Flux.just(DMAAP_MODEL)); + when(aaiQueryTask.findPnfinAAI(DMAAP_MODEL)).thenReturn(Mono.just(DMAAP_MODEL)); + when(aaiQueryTask.execute(DMAAP_MODEL)).thenReturn(Mono.just(true)); + when(aaiProducerTask.execute(state.dmaapModel)).thenThrow(new PrhTaskException()); + + sut.scheduleKafkaPrhEventTask(); + + verifyIfLogicalLinkWasNotCreated(); + verifyThatPnfModelWasNotSentDmaapPnfReadyTopic(); + } + + @Test + void queryAAiForPNFOnPRHExceptionTest() throws JSONException, PrhTaskException { + ScheduledTasksWithCommit.State state = new ScheduledTasksWithCommit.State(DMAAP_MODEL, true); + MessageRouterPublishResponse messageRouterPublishResponse = new MessageRouterPublishResponse() { + @Override + public @Nullable String failReason() { + return null; + } + }; + when(kafkaConsumerTask.execute()).thenReturn(Flux.just(DMAAP_MODEL)); + when(aaiQueryTask.findPnfinAAI(DMAAP_MODEL)).thenReturn(Mono.just(DMAAP_MODEL)); + when(aaiQueryTask.execute(DMAAP_MODEL)).thenReturn(Mono.just(true)); + when(aaiProducerTask.execute(state.dmaapModel)).thenReturn(Mono.just(DMAAP_MODEL)); + when(updatePublisher.execute(state.dmaapModel)).thenThrow(new PrhTaskException()); + + sut.scheduleKafkaPrhEventTask(); + + verifyIfLogicalLinkWasNotCreated(); + verifyThatPnfModelWasNotSentDmaapPnfReadyTopic(); + } + + @Test + void queryAAiForPNFOnPRHExceptionOnDmaapEmptyResponseExceptionTest() throws JSONException, PrhTaskException { + ScheduledTasksWithCommit.State state = new ScheduledTasksWithCommit.State(DMAAP_MODEL, true); + MessageRouterPublishResponse messageRouterPublishResponse = new MessageRouterPublishResponse() { + @Override + public @Nullable String failReason() { + return null; + } + }; + when(kafkaConsumerTask.execute()).thenReturn(Flux.just(DMAAP_MODEL)); + when(aaiQueryTask.findPnfinAAI(DMAAP_MODEL)).thenReturn(Mono.just(DMAAP_MODEL)); + when(aaiQueryTask.execute(DMAAP_MODEL)).thenReturn(Mono.just(true)); + when(aaiProducerTask.execute(state.dmaapModel)).thenReturn(Mono.just(DMAAP_MODEL)); + when(updatePublisher.execute(state.dmaapModel)).thenThrow(new DmaapEmptyResponseException()); + + sut.scheduleKafkaPrhEventTask(); + + verifyIfLogicalLinkWasNotCreated(); + verifyThatPnfModelWasNotSentDmaapPnfReadyTopic(); + } + + @Test + void queryAAiForPNFOnPRHExceptionOnFalseTest() throws JSONException, PrhTaskException { + ScheduledTasksWithCommit.State state = new ScheduledTasksWithCommit.State(DMAAP_MODEL, false); + MessageRouterPublishResponse messageRouterPublishResponse = new MessageRouterPublishResponse() { + @Override + public @Nullable String failReason() { + return null; + } + }; + when(kafkaConsumerTask.execute()).thenReturn(Flux.just(DMAAP_MODEL)); + when(aaiQueryTask.findPnfinAAI(DMAAP_MODEL)).thenReturn(Mono.just(DMAAP_MODEL)); + when(aaiQueryTask.execute(DMAAP_MODEL)).thenReturn(Mono.just(false)); + when(aaiProducerTask.execute(state.dmaapModel)).thenReturn(Mono.just(DMAAP_MODEL)); + + sut.scheduleKafkaPrhEventTask(); + verifyThatPnfModelWasNotSentDmaapPnfReadyTopic(); + } + + @Test + void queryAAiForPNFOnPRHExceptionOnJSONExceptionTest() throws PrhTaskException, JSONException { + ScheduledTasksWithCommit.State state = new ScheduledTasksWithCommit.State(DMAAP_MODEL, true); + MessageRouterPublishResponse messageRouterPublishResponse = new MessageRouterPublishResponse() { + @Override + public @Nullable String failReason() { + return null; + } + }; + when(kafkaConsumerTask.execute()).thenThrow(new JSONException("json format exception")); + + sut.scheduleKafkaPrhEventTask(); + + verifyIfLogicalLinkWasNotCreated(); + verifyThatPnfModelWasNotSentDmaapPnfReadyTopic(); + } + + private void verifyThatPnfModelWasNotSentDmaapPnfReadyTopic() throws PrhTaskException { + verify(readyPublisher, never()).execute(DMAAP_MODEL); + } + + private void verifyThatPnfModelWasNotSentDmaapPnfUpdateTopic() throws PrhTaskException { + verify(updatePublisher, never()).execute(DMAAP_MODEL); + } + + private void verifyThatPnfUpdateWasNotSentToAai() throws PrhTaskException { + verify(aaiProducerTask, never()).execute(DMAAP_MODEL); + } + + private void verifyIfLogicalLinkWasNotCreated(){ + verify(bbsActionsTask, never()).execute(DMAAP_MODEL); + } +} + diff --git a/prh-app-server/src/test/resources/application.yaml b/prh-app-server/src/test/resources/application.yaml index fa7f11cf..85ab663c 100644 --- a/prh-app-server/src/test/resources/application.yaml +++ b/prh-app-server/src/test/resources/application.yaml @@ -2,7 +2,9 @@ spring: profiles: active: prod + + logging: level: org.onap.dcaegen2.services.prh: debug - org.onap.dcaegen2.services.sdk: debug
\ No newline at end of file + org.onap.dcaegen2.services.sdk: debug diff --git a/prh-app-server/src/test/resources/autoCommitDisabledConfigurationFromCbs2.json b/prh-app-server/src/test/resources/autoCommitDisabledConfigurationFromCbs2.json new file mode 100644 index 00000000..6e58e6a5 --- /dev/null +++ b/prh-app-server/src/test/resources/autoCommitDisabledConfigurationFromCbs2.json @@ -0,0 +1,66 @@ +{ + "config": { + "aai.aaiClientConfiguration.aaiBasePath": "/aai/v23", + "aai.aaiClientConfiguration.aaiHeaders": { + "Accept": "application/json", + "Authorization": "Basic QUFJOkFBSQ==", + "Real-Time": "true", + "X-FromAppId": "prh", + "X-TransactionId": "9999" + }, + "aai.aaiClientConfiguration.aaiHost": "aai-internal.onap.svc.cluster.local", + "aai.aaiClientConfiguration.aaiHostPortNumber": 80, + "aai.aaiClientConfiguration.aaiIgnoreSslCertificateErrors": true, + "aai.aaiClientConfiguration.aaiPnfPath": "/network/pnfs/pnf", + "aai.aaiClientConfiguration.aaiProtocol": "http", + "aai.aaiClientConfiguration.aaiServiceInstancePath": "/business/customers/customer/{{customer}}/service-subscriptions/service-subscription/{{serviceType}}/service-instances/service-instance/{{serviceInstanceId}}", + "aai.aaiClientConfiguration.aaiUserName": "AAI", + "aai.aaiClientConfiguration.aaiUserPassword": "AAI", + "aai.aaiClientConfiguration.baseUrl": "https://aai.onap.svc.cluster.local:8443/aai/v23", + "aai.aaiClientConfiguration.pnfUrl": "http://aai.onap.svc.cluster.local:8443/aai/v23/network/pnfs/pnf", + "dmaap.dmaapConsumerConfiguration.consumerGroup": "OpenDCAE-c12", + "dmaap.dmaapConsumerConfiguration.consumerId": "c12", + "dmaap.dmaapConsumerConfiguration.dmaapContentType": "application/json", + "dmaap.dmaapConsumerConfiguration.timeoutMs": -1, + "dmaap.dmaapProducerConfiguration.dmaapContentType": "application/json", + "dmaap.dmaapUpdateProducerConfiguration.dmaapContentType": "application/json", + "security.enableAaiCertAuth": false, + "security.enableDmaapCertAuth": false, + "security.keyStorePasswordPath": "/opt/app/prh/etc/cert/jks.pass", + "security.keyStorePath": "/opt/app/prh/etc/cert/cert.jks", + "security.trustStorePasswordPath": "/opt/app/prh/etc/cert/trust.pass", + "security.trustStorePath": "/opt/app/prh/etc/cert/trust.jks", + "streams_publishes": { + "pnf-ready": { + "dmaap_info": { + "topic_url": "http://dmaap-mr:2222/events/unauthenticated.PNF_READY" + }, + "type": "message_router" + }, + "pnf-update": { + "dmaap_info": { + "topic_url": "http://dmaap-mr:2222/events/unauthenticated.PNF_UPDATE" + }, + "type": "message_router" + } + }, + "streams_subscribes": { + "ves-reg-output": { + "dmaap_info": { + "topic_url": "http://dmaap-mr:2222/events/unauthenticated.VES_PNFREG_OUTPUT" + }, + "type": "message_router" + } + }, + "kafka-configurations": { + "kafkaBoostrapServerConfig": "onap-strimzi-kafka-bootstrap:9092", + "groupIdConfig": "OpenDCAE-c12", + "kafkaSecurityProtocol": "SASL_PLAINTEXT", + "kafkaSaslMechanism": "SCRAM-SHA-512", + "kafkaUsername": "strimzi-kafka-admin-username", + "kafkaPassword": "strimzi-kafka-admin-password", + "kafkaJaasConfig": "jaas_config", + "Login_Module_Class": "MODULE-CLASS" + } + } +} |