summaryrefslogtreecommitdiffstats
path: root/adapters/etsi-sol002-adapter
diff options
context:
space:
mode:
Diffstat (limited to 'adapters/etsi-sol002-adapter')
-rw-r--r--adapters/etsi-sol002-adapter/pom.xml93
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/Application.java36
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/aai/AaiConnection.java136
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/aai/AaiPropertiesExt.java71
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/aai/EsrId.java45
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ApplicationConfiguration.java44
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ConfigProperties.java134
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/StartupConfiguration.java58
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/constant/NotificationVnfFilterType.java41
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/controller/NotificationController.java55
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/event/AaiEvent.java44
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/event/DmaapEvent.java110
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/exception/VeVnfmException.java32
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/provider/AuthorizationHeadersProvider.java39
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/DmaapConditionalSender.java75
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/DmaapService.java70
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/StartupService.java66
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/SubscribeSender.java86
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/SubscriberService.java120
-rw-r--r--adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/SubscriptionScheduler.java101
-rw-r--r--adapters/etsi-sol002-adapter/src/main/resources/META-INF/services/org.onap.so.client.RestProperties1
-rw-r--r--adapters/etsi-sol002-adapter/src/main/resources/application.yaml56
-rw-r--r--adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/controller/NotificationControllerTest.java81
-rw-r--r--adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/provider/AuthorizationHeadersProviderTest.java86
-rw-r--r--adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/DmaapConditionalSenderTest.java135
-rw-r--r--adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/StartupServiceTest.java72
-rw-r--r--adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/SubscribeSenderTest.java107
-rw-r--r--adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/SubscriptionSchedulerTest.java69
28 files changed, 2063 insertions, 0 deletions
diff --git a/adapters/etsi-sol002-adapter/pom.xml b/adapters/etsi-sol002-adapter/pom.xml
new file mode 100644
index 0000000000..b419d8806b
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/pom.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<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>
+
+ <parent>
+ <groupId>org.onap.so</groupId>
+ <artifactId>adapters</artifactId>
+ <version>1.6.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.onap.so.adapters</groupId>
+ <artifactId>etsi-sol002-adapter</artifactId>
+ <packaging>jar</packaging>
+
+ <name>ETSI SOL002 Application Jar</name>
+
+ <properties>
+ <java.version>1.8</java.version>
+ <maven.compiler.source>${java.version}</maven.compiler.source>
+ <maven.compiler.target>${java.version}</maven.compiler.target>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.retry</groupId>
+ <artifactId>spring-retry</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.so.adapters</groupId>
+ <artifactId>etsi-sol003-lcm-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.so.adapters</groupId>
+ <artifactId>etsi-sol003-lcm-ext-clients</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.so</groupId>
+ <artifactId>common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.core</groupId>
+ <artifactId>jersey-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.core</groupId>
+ <artifactId>jersey-client</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.inject</groupId>
+ <artifactId>jersey-hk2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>${project.artifactId}-${project.version}</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <configuration>
+ <mainClass>org.onap.so.adapters.vevnfm.Application</mainClass>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/Application.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/Application.java
new file mode 100644
index 0000000000..875fddd7f0
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/Application.java
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2019 Samsung. 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.so.adapters.vevnfm;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication(scanBasePackages = {"org.onap.so"})
+public class Application {
+
+ public static final String BASIC_PROFILE = "basic";
+
+ public static void main(final String... args) {
+ final SpringApplication springApplication = new SpringApplication(Application.class);
+ springApplication.setAdditionalProfiles(BASIC_PROFILE);
+ springApplication.run(args);
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/aai/AaiConnection.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/aai/AaiConnection.java
new file mode 100644
index 0000000000..038b0e44d3
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/aai/AaiConnection.java
@@ -0,0 +1,136 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.aai;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+import org.apache.logging.log4j.util.Strings;
+import org.onap.aai.domain.yang.*;
+import org.onap.so.adapters.vevnfm.exception.VeVnfmException;
+import org.onap.aaiclient.client.aai.AAIObjectType;
+import org.onap.aaiclient.client.aai.AAIResourcesClient;
+import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
+import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
+import org.onap.aaiclient.client.graphinventory.entities.uri.Depth;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AaiConnection {
+
+ private static final Logger logger = LoggerFactory.getLogger(AaiConnection.class);
+
+ private static final String SELFLINK = "selflink";
+ private static final int FIRST_INDEX = 0;
+
+ private AAIResourcesClient resourcesClient = null;
+
+ private static void isValid(final List<EsrSystemInfo> infos) throws VeVnfmException {
+ if (infos == null || infos.isEmpty() || Strings.isBlank(infos.get(FIRST_INDEX).getServiceUrl())) {
+ throw new VeVnfmException("No 'url' field in VNFM info");
+ }
+ }
+
+ private AAIResourcesClient getResourcesClient() {
+ if (resourcesClient == null) {
+ resourcesClient = new AAIResourcesClient();
+ }
+
+ return resourcesClient;
+ }
+
+ public List<EsrSystemInfo> receiveVnfm() throws VeVnfmException {
+ List<EsrSystemInfo> infos;
+
+ try {
+ infos = receiveVnfmInternal();
+ } catch (Exception e) {
+ throw new VeVnfmException(e);
+ }
+
+ isValid(infos);
+
+ return infos;
+ }
+
+ private List<EsrSystemInfo> receiveVnfmInternal() {
+ final AAIResourceUri resourceUri = AAIUriFactory.createResourceUri(AAIObjectType.VNFM_LIST);
+ final Optional<EsrVnfmList> response = getResourcesClient().get(EsrVnfmList.class, resourceUri);
+
+ if (response.isPresent()) {
+ final EsrVnfmList esrVnfmList = response.get();
+ logger.info("The AAI ESR replied with: {}", esrVnfmList);
+ final List<EsrVnfm> esrVnfm = esrVnfmList.getEsrVnfm();
+
+ final List<EsrSystemInfo> infos = new LinkedList<>();
+
+ for (final EsrVnfm vnfm : esrVnfm) {
+ final String vnfmId = vnfm.getVnfmId();
+ infos.addAll(receiveVnfmServiceUrl(vnfmId));
+ }
+
+ return infos;
+ }
+
+ return null;
+ }
+
+ private List<EsrSystemInfo> receiveVnfmServiceUrl(final String vnfmId) {
+ final Optional<EsrVnfm> response = getResourcesClient().get(EsrVnfm.class,
+ AAIUriFactory.createResourceUri(AAIObjectType.VNFM, vnfmId).depth(Depth.ONE));
+
+ if (response.isPresent()) {
+ final EsrVnfm esrVnfm = response.get();
+ logger.info("The AAI ESR replied with: {}", esrVnfm);
+ final EsrSystemInfoList esrSystemInfoList = esrVnfm.getEsrSystemInfoList();
+
+ if (esrSystemInfoList != null) {
+ return esrSystemInfoList.getEsrSystemInfo();
+ }
+ }
+
+ return Collections.emptyList();
+ }
+
+ public String receiveGenericVnfId(final String href) {
+ final AAIResourceUri resourceUri =
+ AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNFS).queryParam(SELFLINK, href);
+ final Optional<GenericVnfs> response = getResourcesClient().get(GenericVnfs.class, resourceUri);
+
+ if (response.isPresent()) {
+ final GenericVnfs vnfs = response.get();
+ logger.info("The AAI replied with: {}", vnfs);
+ final List<GenericVnf> genericVnfList = vnfs.getGenericVnf();
+ final int size = genericVnfList.size();
+
+ if (size == 1) {
+ return genericVnfList.get(FIRST_INDEX).getVnfId();
+ } else if (size > 1) {
+ logger.warn("more generic vnfs available");
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/aai/AaiPropertiesExt.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/aai/AaiPropertiesExt.java
new file mode 100644
index 0000000000..5e3212a225
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/aai/AaiPropertiesExt.java
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.aai;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import org.onap.so.adapters.vevnfm.configuration.ConfigProperties;
+import org.onap.aaiclient.client.aai.AAIProperties;
+import org.onap.aaiclient.client.aai.AAIVersion;
+import org.onap.so.spring.SpringContextHelper;
+import org.springframework.context.ApplicationContext;
+
+public class AaiPropertiesExt implements AAIProperties {
+
+ private static final String MSO = "MSO";
+
+ private final String endpoint;
+ private final String encryptedBasicAuth;
+ private final String encryptionKey;
+
+ public AaiPropertiesExt() {
+ final ApplicationContext context = SpringContextHelper.getAppContext();
+ final ConfigProperties configProperties = context.getBean(ConfigProperties.class);
+ this.endpoint = configProperties.getAaiEndpoint();
+ this.encryptedBasicAuth = configProperties.getAaiAuth();
+ this.encryptionKey = configProperties.getMsoKey();
+ }
+
+ @Override
+ public URL getEndpoint() throws MalformedURLException {
+ return new URL(endpoint);
+ }
+
+ @Override
+ public String getSystemName() {
+ return MSO;
+ }
+
+ @Override
+ public AAIVersion getDefaultVersion() {
+ return AAIVersion.V15;
+ }
+
+ @Override
+ public String getAuth() {
+ return encryptedBasicAuth;
+ }
+
+ @Override
+ public String getKey() {
+ return encryptionKey;
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/aai/EsrId.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/aai/EsrId.java
new file mode 100644
index 0000000000..13ff2b6397
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/aai/EsrId.java
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.aai;
+
+import org.onap.aai.domain.yang.EsrSystemInfo;
+
+public class EsrId {
+
+ private EsrSystemInfo info;
+ private String id;
+
+ public EsrSystemInfo getInfo() {
+ return info;
+ }
+
+ public void setInfo(final EsrSystemInfo info) {
+ this.info = info;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(final String id) {
+ this.id = id;
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ApplicationConfiguration.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ApplicationConfiguration.java
new file mode 100644
index 0000000000..411572ff5b
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ApplicationConfiguration.java
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.configuration;
+
+import org.onap.so.adapters.vevnfm.provider.AuthorizationHeadersProvider;
+import org.onap.so.configuration.rest.HttpHeadersProvider;
+import org.onap.so.rest.service.HttpRestServiceProvider;
+import org.onap.so.rest.service.HttpRestServiceProviderImpl;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class ApplicationConfiguration {
+
+ @Bean
+ public AuthorizationHeadersProvider headersProvider() {
+ return new AuthorizationHeadersProvider();
+ }
+
+ @Bean
+ public HttpRestServiceProvider restProvider(final RestTemplate restTemplate,
+ final HttpHeadersProvider headersProvider) {
+ return new HttpRestServiceProviderImpl(restTemplate, headersProvider);
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ConfigProperties.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ConfigProperties.java
new file mode 100644
index 0000000000..d4ca5af0f2
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ConfigProperties.java
@@ -0,0 +1,134 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.configuration;
+
+import org.onap.so.adapters.vevnfm.constant.NotificationVnfFilterType;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class ConfigProperties {
+
+ @Value("${vevnfmadapter.vnf-filter-json}")
+ private String vevnfmadapterVnfFilterJson;
+
+ @Value("${vevnfmadapter.endpoint}")
+ private String vevnfmadapterEndpoint;
+
+ @Value("${mso.key}")
+ private String msoKey;
+
+ @Value("${aai.endpoint}")
+ private String aaiEndpoint;
+
+ @Value("${aai.auth}")
+ private String aaiAuth;
+
+ @Value("${vnfm.default-endpoint}")
+ private String vnfmDefaultEndpoint;
+
+ @Value("${vnfm.subscription}")
+ private String vnfmSubscription;
+
+ @Value("${vnfm.notification}")
+ private String vnfmNotification;
+
+ @Value("${notification.vnf-filter-type}")
+ private NotificationVnfFilterType notificationVnfFilterType;
+
+ @Value("${dmaap.endpoint}")
+ private String dmaapEndpoint;
+
+ @Value("${dmaap.topic}")
+ private String dmaapTopic;
+
+ @Value("${dmaap.closed-loop.control.name}")
+ private String dmaapClosedLoopControlName;
+
+ @Value("${dmaap.version}")
+ private String dmaapVersion;
+
+ @Value("${spring.security.usercredentials[0].username}")
+ private String springSecurityUsername;
+
+ @Value("${spring.security.usercredentials[0].openpass}")
+ private String springSecurityOpenpass;
+
+ public String getVevnfmadapterVnfFilterJson() {
+ return vevnfmadapterVnfFilterJson;
+ }
+
+ public String getVevnfmadapterEndpoint() {
+ return vevnfmadapterEndpoint;
+ }
+
+ public String getMsoKey() {
+ return msoKey;
+ }
+
+ public String getAaiEndpoint() {
+ return aaiEndpoint;
+ }
+
+ public String getAaiAuth() {
+ return aaiAuth;
+ }
+
+ public String getVnfmDefaultEndpoint() {
+ return vnfmDefaultEndpoint;
+ }
+
+ public String getVnfmSubscription() {
+ return vnfmSubscription;
+ }
+
+ public String getVnfmNotification() {
+ return vnfmNotification;
+ }
+
+ public NotificationVnfFilterType getNotificationVnfFilterType() {
+ return notificationVnfFilterType;
+ }
+
+ public String getDmaapEndpoint() {
+ return dmaapEndpoint;
+ }
+
+ public String getDmaapTopic() {
+ return dmaapTopic;
+ }
+
+ public String getDmaapClosedLoopControlName() {
+ return dmaapClosedLoopControlName;
+ }
+
+ public String getDmaapVersion() {
+ return dmaapVersion;
+ }
+
+ public String getSpringSecurityUsername() {
+ return springSecurityUsername;
+ }
+
+ public String getSpringSecurityOpenpass() {
+ return springSecurityOpenpass;
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/StartupConfiguration.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/StartupConfiguration.java
new file mode 100644
index 0000000000..8b5afbf6a1
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/StartupConfiguration.java
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.configuration;
+
+import java.util.List;
+import org.onap.aai.domain.yang.EsrSystemInfo;
+import org.onap.so.adapters.vevnfm.service.StartupService;
+import org.onap.so.adapters.vevnfm.service.SubscriptionScheduler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.event.ApplicationReadyEvent;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.event.EventListener;
+import org.springframework.core.env.Environment;
+import org.springframework.core.env.Profiles;
+
+@Configuration
+public class StartupConfiguration {
+
+ public static final String TEST_PROFILE = "test";
+
+ private final Environment environment;
+ private final StartupService startupService;
+ private final SubscriptionScheduler subscriptionScheduler;
+
+ @Autowired
+ public StartupConfiguration(final Environment environment, final StartupService startupService,
+ final SubscriptionScheduler subscriptionScheduler) {
+ this.environment = environment;
+ this.startupService = startupService;
+ this.subscriptionScheduler = subscriptionScheduler;
+ }
+
+ @EventListener(ApplicationReadyEvent.class)
+ public void onApplicationReadyEvent() throws Exception {
+ if (!environment.acceptsProfiles(Profiles.of(TEST_PROFILE))) {
+ final List<EsrSystemInfo> infos = startupService.receiveVnfm();
+ subscriptionScheduler.setInfos(infos);
+ }
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/constant/NotificationVnfFilterType.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/constant/NotificationVnfFilterType.java
new file mode 100644
index 0000000000..57935a9fda
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/constant/NotificationVnfFilterType.java
@@ -0,0 +1,41 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.constant;
+
+/**
+ * Select which incoming Notification with particular VNF id should be supported
+ */
+public enum NotificationVnfFilterType {
+ /**
+ * None
+ */
+ NONE,
+
+ /**
+ * Only those which are valid in AAI
+ */
+ AAI_CHECKED,
+
+ /**
+ * All
+ */
+ ALL
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/controller/NotificationController.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/controller/NotificationController.java
new file mode 100644
index 0000000000..1162ee5605
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/controller/NotificationController.java
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2019 Samsung. 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.so.adapters.vevnfm.controller;
+
+import org.onap.so.adapters.etsisol003adapter.lcm.lcn.model.VnfLcmOperationOccurrenceNotification;
+import org.onap.so.adapters.vevnfm.service.DmaapConditionalSender;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class NotificationController {
+
+ private static final Logger logger = LoggerFactory.getLogger(NotificationController.class);
+
+ private final DmaapConditionalSender dmaapConditionalSender;
+
+ public NotificationController(final DmaapConditionalSender dmaapConditionalSender) {
+ this.dmaapConditionalSender = dmaapConditionalSender;
+ }
+
+ @PostMapping("${vnfm.notification}")
+ public ResponseEntity receiveNotification(@RequestBody final VnfLcmOperationOccurrenceNotification notification) {
+ logger.info("Notification received {}", notification);
+
+ try {
+ dmaapConditionalSender.send(notification);
+ } catch (NullPointerException e) {
+ logger.warn("NullPointerException caught while sending to DMaaP", e);
+ }
+
+ return ResponseEntity.ok().build();
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/event/AaiEvent.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/event/AaiEvent.java
new file mode 100644
index 0000000000..ceabb8a020
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/event/AaiEvent.java
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.event;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class AaiEvent {
+
+ private final boolean vserverIsClosedLoopDisabled;
+ private final String genericVnfVnfId;
+
+ public AaiEvent(final boolean cld, final String id) {
+ this.vserverIsClosedLoopDisabled = cld;
+ this.genericVnfVnfId = id;
+ }
+
+ @JsonProperty("vserver.is-closed-loop-disabled")
+ public boolean isVserverIsClosedLoopDisabled() {
+ return vserverIsClosedLoopDisabled;
+ }
+
+ @JsonProperty("generic-vnf.vnf-id")
+ public String getGenericVnfVnfId() {
+ return genericVnfVnfId;
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/event/DmaapEvent.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/event/DmaapEvent.java
new file mode 100644
index 0000000000..142c6b0399
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/event/DmaapEvent.java
@@ -0,0 +1,110 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.event;
+
+import static java.time.temporal.ChronoField.INSTANT_SECONDS;
+import java.time.Instant;
+import java.util.UUID;
+import org.onap.so.adapters.etsisol003adapter.lcm.lcn.model.VnfLcmOperationOccurrenceNotification;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class DmaapEvent {
+
+ public static final String MSERVICE = "microservice.stringmatcher";
+ public static final String ONSET = "ONSET";
+ public static final String VNF = "VNF";
+ public static final String VNFID = "generic-vnf.vnf-id";
+ public static final String ETSI = "ETSI";
+
+ private final String closedLoopControlName;
+ private final long closedLoopAlarmStart;
+ private final String closedLoopEventClient;
+ private final String closedLoopEventStatus;
+ private final String requestId;
+ private final String targetType;
+ private final String target;
+ private final AaiEvent aaiEvent;
+ private final String from;
+ private final String version;
+ private final VnfLcmOperationOccurrenceNotification etsiLcmEvent;
+
+ public DmaapEvent(final String closedLoopControlName, final String version,
+ final VnfLcmOperationOccurrenceNotification etsiLcmEvent, final String genericId) {
+ this.closedLoopControlName = closedLoopControlName;
+ this.closedLoopAlarmStart = Instant.now().getLong(INSTANT_SECONDS);
+ this.closedLoopEventClient = MSERVICE;
+ this.closedLoopEventStatus = ONSET;
+ this.requestId = UUID.randomUUID().toString();
+ this.targetType = VNF;
+ this.target = VNFID;
+ this.aaiEvent = (genericId == null) ? null : new AaiEvent(false, genericId);
+ this.from = ETSI;
+ this.version = version;
+ this.etsiLcmEvent = etsiLcmEvent;
+ }
+
+ public String getClosedLoopControlName() {
+ return closedLoopControlName;
+ }
+
+ public long getClosedLoopAlarmStart() {
+ return closedLoopAlarmStart;
+ }
+
+ public String getClosedLoopEventClient() {
+ return closedLoopEventClient;
+ }
+
+ public String getClosedLoopEventStatus() {
+ return closedLoopEventStatus;
+ }
+
+ @JsonProperty("requestID")
+ public String getRequestId() {
+ return requestId;
+ }
+
+ @JsonProperty("target_type")
+ public String getTargetType() {
+ return targetType;
+ }
+
+ public String getTarget() {
+ return target;
+ }
+
+ @JsonProperty("AAI")
+ public AaiEvent getAaiEvent() {
+ return aaiEvent;
+ }
+
+ public String getFrom() {
+ return from;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public VnfLcmOperationOccurrenceNotification getEtsiLcmEvent() {
+ return etsiLcmEvent;
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/exception/VeVnfmException.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/exception/VeVnfmException.java
new file mode 100644
index 0000000000..a0c1c1e9db
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/exception/VeVnfmException.java
@@ -0,0 +1,32 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.exception;
+
+public class VeVnfmException extends Exception {
+
+ public VeVnfmException(final String message) {
+ super(message);
+ }
+
+ public VeVnfmException(final Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/provider/AuthorizationHeadersProvider.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/provider/AuthorizationHeadersProvider.java
new file mode 100644
index 0000000000..838a67d115
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/provider/AuthorizationHeadersProvider.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.provider;
+
+import org.apache.logging.log4j.util.Strings;
+import org.onap.so.configuration.rest.BasicHttpHeadersProvider;
+
+public class AuthorizationHeadersProvider extends BasicHttpHeadersProvider {
+
+ public void addAuthorization(final String authorization) {
+ if (Strings.isBlank(authorization)) {
+ return;
+ }
+
+ getHttpHeaders().set(AUTHORIZATION_HEADER, authorization);
+ }
+
+ public void removeAuthorization() {
+ getHttpHeaders().remove(AUTHORIZATION_HEADER);
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/DmaapConditionalSender.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/DmaapConditionalSender.java
new file mode 100644
index 0000000000..bb1d26f523
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/DmaapConditionalSender.java
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.service;
+
+import org.apache.logging.log4j.util.Strings;
+import org.onap.so.adapters.etsisol003adapter.lcm.lcn.model.VnfLcmOperationOccurrenceNotification;
+import org.onap.so.adapters.vevnfm.aai.AaiConnection;
+import org.onap.so.adapters.vevnfm.configuration.ConfigProperties;
+import org.onap.so.adapters.vevnfm.constant.NotificationVnfFilterType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+@Service
+public class DmaapConditionalSender {
+
+ private static final Logger logger = LoggerFactory.getLogger(DmaapConditionalSender.class);
+
+ private final NotificationVnfFilterType notificationVnfFilterType;
+ private final AaiConnection aaiConnection;
+ private final DmaapService dmaapService;
+
+ public DmaapConditionalSender(final ConfigProperties configProperties, final AaiConnection aaiConnection,
+ final DmaapService dmaapService) {
+ this.notificationVnfFilterType = configProperties.getNotificationVnfFilterType();
+ this.aaiConnection = aaiConnection;
+ this.dmaapService = dmaapService;
+ }
+
+ public void send(final VnfLcmOperationOccurrenceNotification notification) {
+ final String href = notification.getLinks().getVnfInstance().getHref();
+ boolean logSent = false;
+
+ switch (notificationVnfFilterType) {
+ case ALL:
+ dmaapService.send(notification, aaiConnection.receiveGenericVnfId(href));
+ logSent = true;
+ break;
+ case AAI_CHECKED:
+ final String genericId = aaiConnection.receiveGenericVnfId(href);
+ if (Strings.isNotBlank(genericId)) {
+ dmaapService.send(notification, genericId);
+ logSent = true;
+ }
+ break;
+ case NONE:
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "The value of VnfNotificationFilterType is not supported: " + notificationVnfFilterType);
+ }
+
+ final String vnfInstanceId = notification.getVnfInstanceId();
+ final String not = logSent ? "" : "not ";
+ logger.info("The info with the VNF id '{}' is " + not + "sent to DMaaP", vnfInstanceId);
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/DmaapService.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/DmaapService.java
new file mode 100644
index 0000000000..4319d78d39
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/DmaapService.java
@@ -0,0 +1,70 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.service;
+
+import org.onap.so.adapters.etsisol003adapter.lcm.lcn.model.VnfLcmOperationOccurrenceNotification;
+import org.onap.so.adapters.vevnfm.configuration.ConfigProperties;
+import org.onap.so.adapters.vevnfm.event.DmaapEvent;
+import org.onap.so.rest.service.HttpRestServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+@Service
+public class DmaapService {
+
+ private static final Logger logger = LoggerFactory.getLogger(DmaapService.class);
+
+ private final String endpoint;
+ private final String topic;
+ private final String closedLoopControlName;
+ private final String version;
+ private final HttpRestServiceProvider restProvider;
+
+ @Autowired
+ public DmaapService(final ConfigProperties configProperties, final HttpRestServiceProvider restProvider) {
+ this.endpoint = configProperties.getDmaapEndpoint();
+ this.topic = configProperties.getDmaapTopic();
+ this.closedLoopControlName = configProperties.getDmaapClosedLoopControlName();
+ this.version = configProperties.getDmaapVersion();
+ this.restProvider = restProvider;
+ }
+
+ public void send(final VnfLcmOperationOccurrenceNotification notification, final String genericId) {
+ try {
+ final DmaapEvent event = new DmaapEvent(closedLoopControlName, version, notification, genericId);
+ final ResponseEntity<String> response = restProvider.postHttpRequest(event, getUrl(), String.class);
+ final HttpStatus statusCode = response.getStatusCode();
+ final String body = response.getBody();
+
+ logger.info("The DMaaP replied with the code {} and the body {}", statusCode, body);
+ } catch (Exception e) {
+ logger.warn("An issue connecting to DMaaP", e);
+ }
+ }
+
+ private String getUrl() {
+ return endpoint + topic;
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/StartupService.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/StartupService.java
new file mode 100644
index 0000000000..c128275e43
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/StartupService.java
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.service;
+
+import java.util.Collections;
+import java.util.List;
+import org.onap.aai.domain.yang.EsrSystemInfo;
+import org.onap.so.adapters.vevnfm.aai.AaiConnection;
+import org.onap.so.adapters.vevnfm.configuration.ConfigProperties;
+import org.onap.so.adapters.vevnfm.exception.VeVnfmException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.retry.annotation.Backoff;
+import org.springframework.retry.annotation.EnableRetry;
+import org.springframework.retry.annotation.Recover;
+import org.springframework.retry.annotation.Retryable;
+import org.springframework.stereotype.Service;
+
+@Service
+@EnableRetry
+public class StartupService {
+
+ private static final Logger logger = LoggerFactory.getLogger(StartupService.class);
+
+ private final String vnfmDefaultEndpoint;
+ private final AaiConnection aaiConnection;
+
+ @Autowired
+ public StartupService(final ConfigProperties configProperties, final AaiConnection aaiConnection) {
+ this.vnfmDefaultEndpoint = configProperties.getVnfmDefaultEndpoint();
+ this.aaiConnection = aaiConnection;
+ }
+
+ @Retryable(value = {Exception.class}, maxAttempts = 5, backoff = @Backoff(delay = 5000, multiplier = 2))
+ public List<EsrSystemInfo> receiveVnfm() throws VeVnfmException {
+ return aaiConnection.receiveVnfm();
+ }
+
+ @Recover
+ public List<EsrSystemInfo> recoverReceiveVnfm(final Throwable t) {
+ logger.warn("Connection to AAI failed");
+ final EsrSystemInfo info = new EsrSystemInfo();
+ info.setServiceUrl(vnfmDefaultEndpoint);
+ logger.warn("This EsrSystemInfo is used by default: {}", info);
+ return Collections.singletonList(info);
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/SubscribeSender.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/SubscribeSender.java
new file mode 100644
index 0000000000..576d58f7be
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/SubscribeSender.java
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.service;
+
+import org.onap.aai.domain.yang.EsrSystemInfo;
+import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.LccnSubscriptionRequest;
+import org.onap.so.adapters.vevnfm.configuration.ConfigProperties;
+import org.onap.so.adapters.vevnfm.exception.VeVnfmException;
+import org.onap.so.rest.service.HttpRestServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.ToString;
+
+@Service
+public class SubscribeSender {
+
+ public static final String SLASH = "/";
+
+ private static final Logger logger = LoggerFactory.getLogger(SubscribeSender.class);
+
+ private final String vnfmSubscription;
+ private final HttpRestServiceProvider restProvider;
+
+ @Autowired
+ public SubscribeSender(final ConfigProperties configProperties, final HttpRestServiceProvider restProvider) {
+ this.vnfmSubscription = configProperties.getVnfmSubscription();
+ this.restProvider = restProvider;
+ }
+
+ public String send(final EsrSystemInfo info, final LccnSubscriptionRequest request) throws VeVnfmException {
+ final ResponseEntity<SubscribeToManoResponse> response =
+ restProvider.postHttpRequest(request, getUrl(info), SubscribeToManoResponse.class);
+
+ final HttpStatus statusCode = response.getStatusCode();
+ final SubscribeToManoResponse body = response.getBody();
+
+ logger.info("The VNFM replied with the code {} and the body {}", statusCode, body);
+
+ if (HttpStatus.CREATED != statusCode) {
+ throw new VeVnfmException("The status code was different than " + HttpStatus.CREATED);
+ }
+
+ return body.id;
+ }
+
+ public boolean check(final EsrSystemInfo info, final String id) {
+ final ResponseEntity<SubscribeToManoResponse> response =
+ restProvider.getHttpResponse(getUrl(info) + SLASH + id, SubscribeToManoResponse.class);
+ return response.getBody() != null && response.getBody().id.equals(id);
+ }
+
+ private String getUrl(final EsrSystemInfo info) {
+ return info.getServiceUrl() + vnfmSubscription;
+ }
+
+ @ToString
+ static class SubscribeToManoResponse {
+ @JsonProperty("id")
+ String id;
+ @JsonProperty("callbackUri")
+ String callbackUri;
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/SubscriberService.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/SubscriberService.java
new file mode 100644
index 0000000000..e9e288b224
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/SubscriberService.java
@@ -0,0 +1,120 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.service;
+
+import java.util.Collections;
+import org.apache.logging.log4j.util.Strings;
+import org.onap.aai.domain.yang.EsrSystemInfo;
+import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.LccnSubscriptionRequest;
+import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.SubscriptionsAuthentication;
+import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.SubscriptionsAuthenticationParamsBasic;
+import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.SubscriptionsFilter;
+import org.onap.so.adapters.vevnfm.configuration.ConfigProperties;
+import org.onap.so.adapters.vevnfm.exception.VeVnfmException;
+import org.onap.so.adapters.vevnfm.provider.AuthorizationHeadersProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.google.gson.Gson;
+import com.squareup.okhttp.Credentials;
+
+@Service
+public class SubscriberService {
+
+ private static final Gson gson = new Gson();
+
+ private final String vnfFilter;
+ private final String endpoint;
+ private final String notification;
+ private final String username;
+ private final String openpass;
+ private final AuthorizationHeadersProvider headersProvider;
+ private final SubscribeSender sender;
+
+ @Autowired
+ public SubscriberService(final ConfigProperties configProperties,
+ final AuthorizationHeadersProvider headersProvider, final SubscribeSender sender) {
+ this.vnfFilter = configProperties.getVevnfmadapterVnfFilterJson();
+ this.endpoint = configProperties.getVevnfmadapterEndpoint();
+ this.notification = configProperties.getVnfmNotification();
+ this.username = configProperties.getSpringSecurityUsername();
+ this.openpass = configProperties.getSpringSecurityOpenpass();
+ this.headersProvider = headersProvider;
+ this.sender = sender;
+ }
+
+ private static String getAuthorization(final EsrSystemInfo info) {
+ if (info == null) {
+ return null;
+ }
+
+ final String userName = info.getUserName();
+
+ if (Strings.isBlank(userName)) {
+ return null;
+ }
+
+ final String password = info.getPassword();
+ return Credentials.basic(userName, password);
+ }
+
+ public String subscribe(final EsrSystemInfo info) throws VeVnfmException {
+ try {
+ headersProvider.addAuthorization(getAuthorization(info));
+ final LccnSubscriptionRequest request = createRequest();
+ return sender.send(info, request);
+ } catch (Exception e) {
+ throw new VeVnfmException(e);
+ } finally {
+ headersProvider.removeAuthorization();
+ }
+ }
+
+ public boolean checkSubscription(final EsrSystemInfo info, final String id) throws VeVnfmException {
+ try {
+ return sender.check(info, id);
+ } catch (Exception e) {
+ throw new VeVnfmException(e);
+ }
+ }
+
+ private LccnSubscriptionRequest createRequest() {
+ final LccnSubscriptionRequest request = new LccnSubscriptionRequest();
+ request.filter(getFilter());
+ request.callbackUri(getCallbackUri());
+ final SubscriptionsAuthenticationParamsBasic paramsBasic = new SubscriptionsAuthenticationParamsBasic();
+ final SubscriptionsAuthentication authentication = new SubscriptionsAuthentication();
+ paramsBasic.setUserName(username);
+ paramsBasic.setPassword(openpass);
+ authentication.setAuthType(Collections.singletonList(SubscriptionsAuthentication.AuthTypeEnum.BASIC));
+ authentication.setParamsBasic(paramsBasic);
+ request.authentication(authentication);
+
+ return request;
+ }
+
+ private SubscriptionsFilter getFilter() {
+ return gson.fromJson(vnfFilter, SubscriptionsFilter.class);
+ }
+
+ private String getCallbackUri() {
+ return endpoint + notification;
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/SubscriptionScheduler.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/SubscriptionScheduler.java
new file mode 100644
index 0000000000..a696336011
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/SubscriptionScheduler.java
@@ -0,0 +1,101 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.service;
+
+import java.util.LinkedList;
+import java.util.List;
+import org.onap.aai.domain.yang.EsrSystemInfo;
+import org.onap.so.adapters.vevnfm.aai.EsrId;
+import org.onap.so.adapters.vevnfm.exception.VeVnfmException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+@Service
+@EnableScheduling
+public class SubscriptionScheduler {
+
+ private static final Logger logger = LoggerFactory.getLogger(SubscriptionScheduler.class);
+
+ private final SubscriberService subscriberService;
+ private List<EsrId> esrIds;
+
+ @Autowired
+ public SubscriptionScheduler(final SubscriberService subscriberService) {
+ this.subscriberService = subscriberService;
+ }
+
+ public void setInfos(final List<EsrSystemInfo> infos) {
+ esrIds = new LinkedList<>();
+
+ for (final EsrSystemInfo info : infos) {
+ final EsrId esrId = new EsrId();
+ esrId.setInfo(info);
+ esrIds.add(esrId);
+ }
+ }
+
+ List<EsrId> getEsrIds() {
+ return esrIds;
+ }
+
+ @Scheduled(fixedRate = 5000, initialDelay = 2000)
+ void subscribeTask() throws VeVnfmException {
+ if (isEsrIdsValid()) {
+ for (final EsrId esrId : esrIds) {
+ singleSubscribe(esrId);
+ }
+ }
+ }
+
+ @Scheduled(fixedRate = 20000)
+ void checkSubscribeTask() throws VeVnfmException {
+ if (isEsrIdsValid()) {
+ for (final EsrId esrId : esrIds) {
+ singleCheckSubscription(esrId);
+ }
+ }
+ }
+
+ private boolean isEsrIdsValid() {
+ return esrIds != null && !esrIds.isEmpty();
+ }
+
+ private void singleSubscribe(final EsrId esrId) throws VeVnfmException {
+ if (esrId.getId() == null) {
+ logger.info("Single subscribe task");
+ esrId.setId(subscriberService.subscribe(esrId.getInfo()));
+ }
+ }
+
+ private void singleCheckSubscription(final EsrId esrId) throws VeVnfmException {
+ if (esrId.getId() != null) {
+ logger.info("Checking subscription: {}", esrId.getId());
+ if (!subscriberService.checkSubscription(esrId.getInfo(), esrId.getId())) {
+ logger.info("Subscription {} not available", esrId.getId());
+ esrId.setId(null);
+ }
+ }
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/main/resources/META-INF/services/org.onap.so.client.RestProperties b/adapters/etsi-sol002-adapter/src/main/resources/META-INF/services/org.onap.so.client.RestProperties
new file mode 100644
index 0000000000..9fc8e62cf5
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/resources/META-INF/services/org.onap.so.client.RestProperties
@@ -0,0 +1 @@
+org.onap.so.adapters.vevnfm.aai.AaiPropertiesExt
diff --git a/adapters/etsi-sol002-adapter/src/main/resources/application.yaml b/adapters/etsi-sol002-adapter/src/main/resources/application.yaml
new file mode 100644
index 0000000000..c69c95187a
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/main/resources/application.yaml
@@ -0,0 +1,56 @@
+#
+# Copyright © 2019, 2020 Samsung.
+# 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.
+
+server:
+ port: 9098
+
+vevnfmadapter:
+ vnf-filter-json: '{notificationTypes:[VnfLcmOperationOccurrenceNotification],operationStates:[COMPLETED]}'
+ endpoint: http://so-ve-vnfm-adapter.onap:9098
+
+mso:
+ key: 07a7159d3bf51a0e53be7a8f89699be7
+
+aai:
+ endpoint: https://aai.onap:30233
+ auth: 75C4483F9C05E2C33A8602635FA532397EC44AB667A2B64DED4FEE08DD932F2E3C1FEE
+
+vnfm:
+ default-endpoint: https://so-vnfm-simulator.onap:9093
+ subscription: /vnflcm/v1/subscriptions
+ notification: /lcm/v1/vnf/instances/notifications
+
+notification:
+ vnf-filter-type: NONE
+
+dmaap:
+ endpoint: http://message-router.onap:30227
+ topic: /events/unauthenticated.DCAE_CL_OUTPUT
+ closed-loop:
+ control:
+ name: ClosedLoopControlName
+ version: 1.0.2
+
+spring:
+ security:
+ usercredentials:
+ - username: admin
+ openpass: a4b3c2d1
+ password: '$2a$10$vU.mWyNTsikAxXIA5c269ewCpAbYTiyMS0m1N.kn4F2CSGEnrKN7K'
+ role: USER
+ http:
+ converters:
+ preferred-json-mapper: gson
diff --git a/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/controller/NotificationControllerTest.java b/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/controller/NotificationControllerTest.java
new file mode 100644
index 0000000000..9406b299ea
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/controller/NotificationControllerTest.java
@@ -0,0 +1,81 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2019 Samsung. 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.so.adapters.vevnfm.controller;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.so.adapters.vevnfm.configuration.ConfigProperties;
+import org.onap.so.adapters.vevnfm.configuration.StartupConfiguration;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+@SpringBootTest
+@RunWith(SpringRunner.class)
+@ActiveProfiles(StartupConfiguration.TEST_PROFILE)
+public class NotificationControllerTest {
+
+ private static final String JSON = "{\"_links\":{\"vnfInstance\":{\"href\":null}}}";
+
+ private static final int ZERO = 0;
+
+ @Autowired
+ private ConfigProperties configProperties;
+
+ @Autowired
+ private WebApplicationContext webApplicationContext;
+
+ private String notification;
+ private MockMvc mvc;
+
+ @Before
+ public void init() {
+ notification = configProperties.getVnfmNotification();
+ mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
+ }
+
+ @Test
+ public void testReceiveNotification() throws Exception {
+ // given
+ final MockHttpServletRequestBuilder request =
+ MockMvcRequestBuilders.post(notification).contentType(MediaType.APPLICATION_JSON).content(JSON);
+
+ // when
+ final MvcResult mvcResult = mvc.perform(request).andReturn();
+
+ // then
+ final MockHttpServletResponse response = mvcResult.getResponse();
+ assertEquals(HttpStatus.OK.value(), response.getStatus());
+ assertEquals(ZERO, response.getContentLength());
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/provider/AuthorizationHeadersProviderTest.java b/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/provider/AuthorizationHeadersProviderTest.java
new file mode 100644
index 0000000000..f9ae427086
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/provider/AuthorizationHeadersProviderTest.java
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.provider;
+
+import static org.junit.Assert.*;
+import static org.onap.so.configuration.rest.BasicHttpHeadersProvider.AUTHORIZATION_HEADER;
+import org.junit.Test;
+import org.springframework.http.HttpHeaders;
+
+public class AuthorizationHeadersProviderTest {
+
+ private static final String AUTHORIZATION_EXAMPLE = "authorization";
+ private static final String BLANK_EXAMPLE = "\t\n";
+ private static final String EMPTY = "";
+
+ private final AuthorizationHeadersProvider provider = new AuthorizationHeadersProvider();
+
+ @Test
+ public void testSuccessValidAuthorizationAndRemoval() {
+ final HttpHeaders headers = provider.getHttpHeaders();
+ final int size = headers.size();
+
+ provider.addAuthorization(AUTHORIZATION_EXAMPLE);
+ assertEquals(size + 1, headers.size());
+ assertTrue(headers.containsKey(AUTHORIZATION_HEADER));
+
+ provider.removeAuthorization();
+ assertEquals(size, headers.size());
+ assertFalse(headers.containsKey(AUTHORIZATION_HEADER));
+ }
+
+ @Test
+ public void testBlankAuthorization() {
+ final HttpHeaders headers = provider.getHttpHeaders();
+ final int size = headers.size();
+
+ provider.addAuthorization(BLANK_EXAMPLE);
+ assertEquals(size, headers.size());
+ }
+
+ @Test
+ public void testEmptyAuthorization() {
+ final HttpHeaders headers = provider.getHttpHeaders();
+ final int size = headers.size();
+
+ provider.addAuthorization(EMPTY);
+ assertEquals(size, headers.size());
+ }
+
+ @Test
+ public void testNullAuthorization() {
+ final HttpHeaders headers = provider.getHttpHeaders();
+ final int size = headers.size();
+
+ provider.addAuthorization(null);
+ assertEquals(size, headers.size());
+ }
+
+ @Test
+ public void testRemoveAuthorization() {
+ final HttpHeaders headers = provider.getHttpHeaders();
+ final int size = headers.size();
+
+ provider.removeAuthorization();
+ provider.removeAuthorization();
+ assertEquals(size, headers.size());
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/DmaapConditionalSenderTest.java b/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/DmaapConditionalSenderTest.java
new file mode 100644
index 0000000000..b430c2bb7a
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/DmaapConditionalSenderTest.java
@@ -0,0 +1,135 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.service;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.so.adapters.etsisol003adapter.lcm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationLinks;
+import org.onap.so.adapters.etsisol003adapter.lcm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance;
+import org.onap.so.adapters.etsisol003adapter.lcm.lcn.model.VnfLcmOperationOccurrenceNotification;
+import org.onap.so.adapters.vevnfm.aai.AaiConnection;
+import org.onap.so.adapters.vevnfm.configuration.ConfigProperties;
+import org.onap.so.adapters.vevnfm.constant.NotificationVnfFilterType;
+
+@RunWith(MockitoJUnitRunner.class)
+public class DmaapConditionalSenderTest {
+
+ private static final String GENERIC_ID = "gener77";
+ private static final String INSTANCE_ID = "insta44";
+ private static final String HREF = "/href";
+
+ @Mock
+ private ConfigProperties configProperties;
+
+ @Mock
+ private AaiConnection aaiConnection;
+
+ @Mock
+ private DmaapService dmaapService;
+
+ private static VnfLcmOperationOccurrenceNotification createNotification() {
+ final VnfLcmOperationOccurrenceNotification notification = new VnfLcmOperationOccurrenceNotification();
+ final LcnVnfLcmOperationOccurrenceNotificationLinks links = new LcnVnfLcmOperationOccurrenceNotificationLinks();
+ final LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance vnfInstance =
+ new LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance();
+
+ notification.setVnfInstanceId(INSTANCE_ID);
+ notification.setLinks(links);
+ links.setVnfInstance(vnfInstance);
+ vnfInstance.setHref(HREF);
+
+ return notification;
+ }
+
+ @Test
+ public void testSendNone() {
+ // given
+ when(configProperties.getNotificationVnfFilterType()).thenReturn(NotificationVnfFilterType.NONE);
+
+ final DmaapConditionalSender sender = new DmaapConditionalSender(configProperties, aaiConnection, dmaapService);
+ final VnfLcmOperationOccurrenceNotification notification = createNotification();
+
+ // when
+ sender.send(notification);
+
+ // then
+ verify(aaiConnection, never()).receiveGenericVnfId(any());
+ verify(dmaapService, never()).send(any(), any());
+ }
+
+ @Test
+ public void testSendAll() {
+ // given
+ when(configProperties.getNotificationVnfFilterType()).thenReturn(NotificationVnfFilterType.ALL);
+ when(aaiConnection.receiveGenericVnfId(eq(HREF))).thenReturn(GENERIC_ID);
+
+ final DmaapConditionalSender sender = new DmaapConditionalSender(configProperties, aaiConnection, dmaapService);
+ final VnfLcmOperationOccurrenceNotification notification = createNotification();
+
+ // when
+ sender.send(notification);
+
+ // then
+ verify(aaiConnection).receiveGenericVnfId(eq(HREF));
+ verify(dmaapService).send(eq(notification), eq(GENERIC_ID));
+ }
+
+ @Test
+ public void testSendAaiCheckedPresent() {
+ // given
+ when(configProperties.getNotificationVnfFilterType()).thenReturn(NotificationVnfFilterType.AAI_CHECKED);
+ when(aaiConnection.receiveGenericVnfId(eq(HREF))).thenReturn(GENERIC_ID);
+
+ final DmaapConditionalSender sender = new DmaapConditionalSender(configProperties, aaiConnection, dmaapService);
+ final VnfLcmOperationOccurrenceNotification notification = createNotification();
+
+ // when
+ sender.send(notification);
+
+ // then
+ verify(aaiConnection).receiveGenericVnfId(eq(HREF));
+ verify(dmaapService).send(eq(notification), eq(GENERIC_ID));
+ }
+
+ @Test
+ public void testSendAaiCheckedAbsent() {
+ // given
+ when(configProperties.getNotificationVnfFilterType()).thenReturn(NotificationVnfFilterType.AAI_CHECKED);
+ when(aaiConnection.receiveGenericVnfId(eq(HREF))).thenReturn(null);
+
+ final DmaapConditionalSender sender = new DmaapConditionalSender(configProperties, aaiConnection, dmaapService);
+ final VnfLcmOperationOccurrenceNotification notification = createNotification();
+
+ // when
+ sender.send(notification);
+
+ // then
+ verify(aaiConnection).receiveGenericVnfId(eq(HREF));
+ verify(dmaapService, never()).send(any(), any());
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/StartupServiceTest.java b/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/StartupServiceTest.java
new file mode 100644
index 0000000000..78d6ba899d
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/StartupServiceTest.java
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.service;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.aai.domain.yang.EsrSystemInfo;
+import org.onap.so.adapters.vevnfm.aai.AaiConnection;
+import org.onap.so.adapters.vevnfm.configuration.ConfigProperties;
+
+@RunWith(MockitoJUnitRunner.class)
+public class StartupServiceTest {
+
+ private static final String URL = "rt";
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Mock
+ private ConfigProperties configProperties;
+
+ @Mock
+ private AaiConnection aaiConnection;
+
+ @InjectMocks
+ private StartupService startupService;
+
+ @Test
+ public void testSuccess() throws Exception {
+ // given
+ final EsrSystemInfo info = new EsrSystemInfo();
+ info.setServiceUrl(URL);
+ final List<EsrSystemInfo> infos = Collections.singletonList(info);
+
+ when(aaiConnection.receiveVnfm()).thenReturn(infos);
+
+ // when
+ final List<EsrSystemInfo> systemInfo = startupService.receiveVnfm();
+
+ // then
+ verify(aaiConnection).receiveVnfm();
+ assertEquals(infos, systemInfo);
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/SubscribeSenderTest.java b/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/SubscribeSenderTest.java
new file mode 100644
index 0000000000..265bce043c
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/SubscribeSenderTest.java
@@ -0,0 +1,107 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.service;
+
+import static org.junit.Assert.assertEquals;
+import static org.onap.so.adapters.vevnfm.service.SubscribeSender.SLASH;
+import static org.springframework.http.HttpHeaders.CONTENT_TYPE;
+import static org.springframework.test.web.client.ExpectedCount.once;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.header;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
+import org.hamcrest.CoreMatchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aai.domain.yang.EsrSystemInfo;
+import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.LccnSubscriptionRequest;
+import org.onap.so.adapters.vevnfm.configuration.ConfigProperties;
+import org.onap.so.adapters.vevnfm.configuration.StartupConfiguration;
+import org.onap.so.adapters.vevnfm.exception.VeVnfmException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.client.MockRestServiceServer;
+import org.springframework.web.client.RestTemplate;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+@SpringBootTest
+@RunWith(SpringRunner.class)
+@ActiveProfiles(StartupConfiguration.TEST_PROFILE)
+public class SubscribeSenderTest {
+
+ private static final String URL = "lh";
+ private static final String ID = "1a2s3d4f";
+ private static final String JSON = "{\"id\":\"" + ID + "\"}";
+
+ private static final Gson GSON;
+
+ static {
+ final GsonBuilder builder = new GsonBuilder();
+ builder.serializeNulls();
+ GSON = builder.create();
+ }
+
+ @Autowired
+ private ConfigProperties configProperties;
+
+ @Autowired
+ private SubscribeSender sender;
+
+ @Autowired
+ private RestTemplate restTemplate;
+
+ private String vnfmSubscription;
+ private MockRestServiceServer mockRestServer;
+
+ @Before
+ public void init() {
+ vnfmSubscription = configProperties.getVnfmSubscription();
+ mockRestServer = MockRestServiceServer.bindTo(restTemplate).build();
+ }
+
+ @Test
+ public void testSuccess() throws VeVnfmException {
+ // given
+ final EsrSystemInfo info = new EsrSystemInfo();
+ info.setServiceUrl(URL);
+ final LccnSubscriptionRequest request = new LccnSubscriptionRequest();
+
+ mockRestServer.expect(once(), requestTo(SLASH + info.getServiceUrl() + vnfmSubscription))
+ .andExpect(header(CONTENT_TYPE, CoreMatchers.containsString(MediaType.APPLICATION_JSON_VALUE)))
+ .andExpect(method(HttpMethod.POST)).andExpect(content().json(GSON.toJson(request)))
+ .andRespond(withStatus(HttpStatus.CREATED).body(JSON).contentType(MediaType.APPLICATION_JSON));
+
+ // when
+ final String id = sender.send(info, request);
+
+ // then
+ mockRestServer.verify();
+ assertEquals(ID, id);
+ }
+}
diff --git a/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/SubscriptionSchedulerTest.java b/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/SubscriptionSchedulerTest.java
new file mode 100644
index 0000000000..d3da7c86ec
--- /dev/null
+++ b/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/SubscriptionSchedulerTest.java
@@ -0,0 +1,69 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SO
+ * ================================================================================
+ * Copyright (C) 2020 Samsung. 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.so.adapters.vevnfm.service;
+
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.aai.domain.yang.EsrSystemInfo;
+
+@RunWith(MockitoJUnitRunner.class)
+public class SubscriptionSchedulerTest {
+
+ private static final String URL = "url";
+ private static final String ID = "id044";
+
+ @Mock
+ private SubscriberService subscriberService;
+
+ @InjectMocks
+ private SubscriptionScheduler subscriptionScheduler;
+
+ @Test
+ public void testFullScenario() throws Exception {
+ // given
+ final EsrSystemInfo info = new EsrSystemInfo();
+ info.setServiceUrl(URL);
+ final List<EsrSystemInfo> infos = Collections.singletonList(info);
+
+ when(subscriberService.subscribe(eq(info))).thenReturn(ID);
+ when(subscriberService.checkSubscription(eq(info), eq(ID))).thenReturn(false);
+
+ // when
+ subscriptionScheduler.setInfos(infos);
+ subscriptionScheduler.subscribeTask();
+ subscriptionScheduler.checkSubscribeTask();
+
+ // then
+ verify(subscriberService).subscribe(info);
+ verify(subscriberService).checkSubscription(info, ID);
+
+ assertNull(subscriptionScheduler.getEsrIds().get(0).getId());
+ }
+}