diff options
Diffstat (limited to 'adapters/etsi-sol002-adapter')
28 files changed, 2056 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..70e4e1d88b --- /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.so.client.aai.AAIObjectType; +import org.onap.so.client.aai.AAIResourcesClient; +import org.onap.so.client.aai.entities.uri.AAIResourceUri; +import org.onap.so.client.aai.entities.uri.AAIUriFactory; +import org.onap.so.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..e8660086c0 --- /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.so.client.aai.AAIProperties; +import org.onap.so.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..36bc23d1b5 --- /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.etsi.sol003.adapter.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..a3ff2dcd6d --- /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 com.fasterxml.jackson.annotation.JsonProperty; +import java.time.Instant; +import java.util.UUID; +import org.onap.so.adapters.etsi.sol003.adapter.lcm.lcn.model.VnfLcmOperationOccurrenceNotification; + +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..b96bffa58f --- /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.etsi.sol003.adapter.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..278f9dee95 --- /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.etsi.sol003.adapter.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..be71c04c89 --- /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 com.fasterxml.jackson.annotation.JsonProperty; +import org.onap.aai.domain.yang.EsrSystemInfo; +import org.onap.so.adapters.vevnfm.configuration.ConfigProperties; +import org.onap.so.adapters.vevnfm.exception.VeVnfmException; +import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.vnfm.model.LccnSubscriptionRequest; +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 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..32cd6ae22f --- /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 com.google.gson.Gson; +import com.squareup.okhttp.Credentials; +import java.util.Collections; +import org.apache.logging.log4j.util.Strings; +import org.onap.aai.domain.yang.EsrSystemInfo; +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.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.vnfm.model.LccnSubscriptionRequest; +import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.vnfm.model.SubscriptionsAuthentication; +import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.vnfm.model.SubscriptionsAuthenticationParamsBasic; +import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.vnfm.model.SubscriptionsFilter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@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..5af682dda8 --- /dev/null +++ b/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/DmaapConditionalSenderTest.java @@ -0,0 +1,131 @@ +/*- + * ============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.Mockito.*; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.so.adapters.etsi.sol003.adapter.lcm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationLinks; +import org.onap.so.adapters.etsi.sol003.adapter.lcm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance; +import org.onap.so.adapters.etsi.sol003.adapter.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..e67e19fd8d --- /dev/null +++ b/adapters/etsi-sol002-adapter/src/test/java/org/onap/so/adapters/vevnfm/service/SubscribeSenderTest.java @@ -0,0 +1,104 @@ +/*- + * ============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.*; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +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.vevnfm.configuration.ConfigProperties; +import org.onap.so.adapters.vevnfm.configuration.StartupConfiguration; +import org.onap.so.adapters.vevnfm.exception.VeVnfmException; +import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.vnfm.model.LccnSubscriptionRequest; +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; + +@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()); + } +} |