Add Tests for VNF Package Mgmt - Subscribe and Notify 00/117800/1
authorAndrewLamb <andrew.a.lamb@est.tech>
Fri, 12 Feb 2021 13:58:36 +0000 (13:58 +0000)
committerAndrewLamb <andrew.a.lamb@est.tech>
Fri, 12 Feb 2021 14:39:54 +0000 (14:39 +0000)
Change-Id: Ie6a14445f3b90975ec579ebf96c806365a01b8ca
Issue-ID: INT-1847
Signed-off-by: AndrewLamb <andrew.a.lamb@est.tech>
20 files changed:
plans/so/integration-etsi-testing/config/override-files/bpmn-infra/onapheat/override.yaml
plans/so/integration-etsi-testing/config/override-files/so-vnfm-adapter/onapheat/override.yaml
plans/so/integration-etsi-testing/config/override-files/vnfm-simulator/onapheat/override.yaml
plans/so/integration-etsi-testing/docker-compose.yml
plans/so/integration-etsi-testing/so-simulators/vnfm-simulator/vnfm-service/pom.xml
plans/so/integration-etsi-testing/so-simulators/vnfm-simulator/vnfm-service/src/main/java/org/onap/so/svnfm/simulator/config/ApplicationConfig.java
plans/so/integration-etsi-testing/so-simulators/vnfm-simulator/vnfm-service/src/main/java/org/onap/so/svnfm/simulator/constants/Constant.java
plans/so/integration-etsi-testing/so-simulators/vnfm-simulator/vnfm-service/src/main/java/org/onap/so/svnfm/simulator/controller/SubscriptionNotificationController.java
plans/so/integration-etsi-testing/so-simulators/vnfm-simulator/vnfm-service/src/main/java/org/onap/so/svnfm/simulator/services/SubscriptionManager.java
plans/so/integration-etsi-testing/so-simulators/vnfm-simulator/vnfm-service/src/main/java/org/onap/so/svnfm/simulator/services/providers/VnfPkgOnboardingNotificationCacheServiceProvider.java [new file with mode: 0644]
plans/so/integration-etsi-testing/so-simulators/vnfm-simulator/vnfm-service/src/main/java/org/onap/so/svnfm/simulator/services/providers/VnfPkgOnboardingNotificationCacheServiceProviderImpl.java [new file with mode: 0644]
plans/so/integration-etsi-testing/so-simulators/vnfm-simulator/vnfm-service/src/main/resources/application.yaml
plans/so/integration-etsi-testing/so-simulators/vnfm-simulator/vnfm-service/src/test/java/org/onap/so/svnfm/simulator/controllers/TestSubscriptionNotificationController.java
plans/so/integration-etsi-testing/so-simulators/vnfm-simulator/vnfm-service/src/test/resources/application.yaml
plans/so/integration-etsi-testing/so-simulators/vnfm-simulator/vnfm-service/src/test/resources/test-data/vnf-package-onboarding-notification.json
plans/so/integration-etsi-testing/testplan.txt
tests/so/etsi/data/responses/expectedVnfPackage.json
tests/so/etsi/data/subscriptionRequest.json [new file with mode: 0644]
tests/so/etsi/etsi_vnf_notification_tests.robot [new file with mode: 0644]
tests/so/etsi/etsi_vnf_subscription_tests.robot [new file with mode: 0644]

index 684c675..87e3066 100644 (file)
@@ -358,7 +358,7 @@ spring:
 so:
   vnfm:
     adapter:
-      url: http://so-vnfm-adapter:9092/so/vnfm-adapter/v1/
+      url: http://so-vnfm-adapter.onap:9092/so/vnfm-adapter/v1/
       auth: Basic dm5mbTpwYXNzd29yZDEk
 org:
   onap:
index 99c9dbd..38c2f6d 100644 (file)
@@ -28,7 +28,7 @@ sdc:
   endpoint: http://sdc-simulator:9991/
   toscametapath: Artifacts/Deployment/OTHER/TOSCA.meta
 vnfmadapter:
-  endpoint: http://so-vnfm-adapter:9092
+  endpoint: http://so-vnfm-adapter.onap:9092
 etsi-catalog-manager:
   vnfpkgm:
     endpoint: http://modeling-etsicatalog:8806/api/vnfpkgm/v1
index b57d0e8..b0f54e3 100644 (file)
@@ -21,17 +21,17 @@ server:
   tomcat:
     max-threads: 50
   ssl:
-    client-auth: need
-    key-alias: so@so.onap.org
-    key--store-password: '7Em3&j4.19xYiMelhD5?xbQ.'
-    key-store: classpath:so-vnfm-simulator.p12
-    key-store-type: PKCS12
+    enabled: false
   request:
     grant:
-      auth: twowaytls
+      auth: none
   dns:
     name: so-vnfm-simulator
 
+vnfm-adapter:
+  base:
+    endpoint: http://so-vnfm-adapter.onap:9092
+
 vnfds:
   vnfdlist:
   -  vnfdid: sgsn-mme_12df452s04131
index f1853e0..cc75311 100644 (file)
@@ -159,6 +159,8 @@ services:
       - DB_ADMIN_PASSWORD=so_Admin123
     hostname:
       bpmn-infra.so.testlab.onap.org
+    links:
+      - "so-vnfm-adapter:so-vnfm-adapter.onap"
     depends_on:
       - mariadb
       - catalog-db-adapter
@@ -288,6 +290,8 @@ services:
       - JVM_ARGS=-Xms64m -Xmx512m
     hostname:
       so-vnfm-simulator
+    links:
+      - "so-vnfm-adapter:so-vnfm-adapter.onap"
     depends_on:
       - mariadb
       - so-vnfm-adapter
@@ -361,6 +365,8 @@ services:
       - SDC_ADDR=http://sdc-simulator:9991
     hostname:
       modeling-etsicatalog
+    links:
+      - "so-vnfm-adapter:so-vnfm-adapter.onap"
     depends_on:
       - mariadb
       - sdc-simulator
index 00fd81f..bd507ca 100644 (file)
       <artifactId>httpclient</artifactId>
       <version>4.5.8</version>
     </dependency>
+    <dependency>
+      <groupId>org.onap.so.simulators</groupId>
+      <artifactId>common</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
   <build>
     <plugins>
index b465792..2e11714 100644 (file)
@@ -1,7 +1,10 @@
 package org.onap.so.svnfm.simulator.config;
 
-import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
 import org.onap.so.svnfm.simulator.constants.Constant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.ApplicationArguments;
@@ -16,6 +19,7 @@ import org.springframework.stereotype.Component;
 
 @Component
 public class ApplicationConfig implements ApplicationRunner {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationConfig.class);
 
     private static final String PORT = "local.server.port";
 
@@ -45,9 +49,18 @@ public class ApplicationConfig implements ApplicationRunner {
 
     @Bean
     public CacheManager cacheManager() {
-        final Cache inlineResponse201 = new ConcurrentMapCache(Constant.IN_LINE_RESPONSE_201_CACHE);
+        final Cache inlineResponse201 = getCache(Constant.IN_LINE_RESPONSE_201_CACHE);
+        final Cache vnfPkgOnboardingNotificationCache = getCache(Constant.VNF_PKG_ONBOARDING_NOTIFICATION_CACHE);
+        final List<Cache> caches = new ArrayList<>();
+        caches.add(inlineResponse201);
+        caches.add(vnfPkgOnboardingNotificationCache);
         final SimpleCacheManager manager = new SimpleCacheManager();
-        manager.setCaches(Arrays.asList(inlineResponse201));
+        manager.setCaches(caches);
         return manager;
     }
+
+    private Cache getCache(final String name) {
+        LOGGER.info("Creating cache with name: {}", name);
+        return new ConcurrentMapCache(name);
+    }
 }
index ceb5be5..c35be6d 100644 (file)
@@ -37,9 +37,11 @@ public class Constant {
     public static final String VNF_CONFIG_PROPERTIES =
             "{\"isAutoScaleEnabled\": \"true\",\"isAutoHealingEnabled\": \"true\"}";
     public static final String IN_LINE_RESPONSE_201_CACHE = "inlineResponse201";
+    public static final String VNF_PKG_ONBOARDING_NOTIFICATION_CACHE = "vnfPackageOnboardingNotificationCache";
     public static final String PACKAGE_MANAGEMENT_BASE_URL = "/vnfpkgm/v1";
     public static final String SUBSCRIPTION_ENDPOINT = "/subscribe";
     public static final String NOTIFICATION_ENDPOINT = "/notification";
-    public static final String VNFM_ADAPTER_ENDPOINT = "https://so-vnfm-adapter.onap:9092/so/vnfm-adapter/v1/";
+    public static final String NOTIFICATION_CACHE_TEST_ENDPOINT = "/notification-cache-test/{vnfPkgId}";
+    public static final String VNFM_ADAPTER_ENDPOINT = "/so/vnfm-adapter/v1/";
     public static final String VNFM_ADAPTER_SUBSCRIPTION_ENDPOINT = VNFM_ADAPTER_ENDPOINT + "vnfpkgm/v1/subscriptions";
 }
index 2c6b8f2..1db20fa 100644 (file)
 package org.onap.so.svnfm.simulator.controller;
 
 import javax.ws.rs.core.MediaType;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.InlineResponse201;
 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.PkgmSubscriptionRequest;
 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsAuthentication;
 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsAuthentication.AuthTypeEnum;
 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsAuthenticationParamsBasic;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.notification.model.VnfPackageChangeNotification;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.notification.model.VnfPackageOnboardingNotification;
 import org.onap.so.svnfm.simulator.constants.Constant;
 import org.onap.so.svnfm.simulator.services.SubscriptionManager;
+import org.onap.so.svnfm.simulator.services.providers.VnfPkgOnboardingNotificationCacheServiceProviderImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Optional;
 
 /**
  * @author Eoin Hanan (eoin.hanan@est.tech)
@@ -47,10 +63,18 @@ import org.springframework.web.bind.annotation.RestController;
 @RestController
 @RequestMapping(path = Constant.PACKAGE_MANAGEMENT_BASE_URL, produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
 public class SubscriptionNotificationController {
+
+    private static final Logger logger = LoggerFactory.getLogger(SubscriptionNotificationController.class);
+    private final Gson gson;
     @Autowired
     private SubscriptionManager subscriptionManager;
+    @Autowired
+    private VnfPkgOnboardingNotificationCacheServiceProviderImpl vnfPkgOnboardingNotificationCacheServiceProvider;
 
-    private static final Logger logger = LoggerFactory.getLogger(SubscriptionNotificationController.class);
+    @Autowired
+    public SubscriptionNotificationController() {
+        this.gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter()).create();
+    }
 
     @Value("${spring.security.usercredentials[0].username}")
     private String username;
@@ -99,9 +123,94 @@ public class SubscriptionNotificationController {
      * @return
      */
     @PostMapping(value = Constant.NOTIFICATION_ENDPOINT, produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    public ResponseEntity<?> postVnfPackageNotification(@RequestBody Object notification){
+    public ResponseEntity<?> postVnfPackageNotification(@RequestBody final Object notification){
         logger.info("Vnf Notification received:\n{}", notification);
+        final String notificationString = gson.toJson(notification);
+        addNotificationObjectToCache(notificationString);
         return ResponseEntity.noContent().build();
     }
 
+    /**
+     * Testing endpoint for checking that notifications have been received
+     *
+     * @param vnfPkgId
+     * @return
+     */
+    @GetMapping(value = Constant.NOTIFICATION_CACHE_TEST_ENDPOINT)
+    public ResponseEntity<?> getVnfPackageNotification(@PathVariable("vnfPkgId") final String vnfPkgId) {
+        logger.info("Getting notification with vnfPkgId: {}", vnfPkgId);
+        final Optional<VnfPackageOnboardingNotification> optionalVnfPackageOnboardingNotification =
+                vnfPkgOnboardingNotificationCacheServiceProvider.getVnfPkgOnboardingNotification(vnfPkgId);
+        if(optionalVnfPackageOnboardingNotification.isPresent()) {
+            VnfPackageOnboardingNotification vnfPackageOnboardingNotification =
+                    optionalVnfPackageOnboardingNotification.get();
+            logger.info("Return notification with vnfPkgId: {} and body {}", vnfPkgId, vnfPackageOnboardingNotification);
+            return ResponseEntity.ok().body(vnfPackageOnboardingNotification);
+        }
+        final String errorMessage = "No notification found with vnfPkgId: " + vnfPkgId;
+        logger.error(errorMessage);
+        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorMessage);
+    }
+
+    private void addNotificationObjectToCache(final String notification) {
+        logger.info("addNotificationObjectToCache(): {}", notification);
+        final String notificationType = getNotificationType(notification);
+        if (VnfPackageOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION.getValue()
+                .equals(notificationType)) {
+            final VnfPackageOnboardingNotification pkgOnboardingNotification =
+                    gson.fromJson(notification, VnfPackageOnboardingNotification.class);
+            logger.info("Onboarding notification received:\n{}", pkgOnboardingNotification);
+            final String vnfPkgId = pkgOnboardingNotification.getVnfPkgId();
+            vnfPkgOnboardingNotificationCacheServiceProvider.addVnfPkgOnboardingNotification(vnfPkgId, pkgOnboardingNotification);
+        } else if (VnfPackageChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION.getValue()
+                .equals(notificationType)) {
+            final VnfPackageChangeNotification pkgChangeNotification =
+                    gson.fromJson(notification, VnfPackageChangeNotification.class);
+            logger.info("Change notification received:\n{}", pkgChangeNotification);
+        } else {
+            final String errorMessage = "An error occurred.  Notification type not supported for: " + notificationType;
+            logger.error(errorMessage);
+            throw new RuntimeException(errorMessage);
+        }
+    }
+
+    private String getNotificationType(final String notification) {
+        try {
+            logger.info("getNotificationType() notification: {}", notification);
+            final JsonParser parser = new JsonParser();
+            final JsonObject element = (JsonObject) parser.parse(notification);
+            return element.get("notificationType").getAsString();
+        } catch (final Exception e) {
+            logger.error("An error occurred processing notificiation: {}", e.getMessage());
+        }
+        throw new RuntimeException(
+                "Unable to parse notification type in object \n" + notification);
+    }
+
+    public static class LocalDateTimeTypeAdapter extends TypeAdapter<LocalDateTime> {
+
+        private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        @Override
+        public void write(final JsonWriter out, final LocalDateTime localDateTime) throws IOException {
+            if (localDateTime == null) {
+                out.nullValue();
+            } else {
+                out.value(FORMATTER.format(localDateTime));
+            }
+        }
+
+        @Override
+        public LocalDateTime read(final JsonReader in) throws IOException {
+            switch (in.peek()) {
+                case NULL:
+                    in.nextNull();
+                    return null;
+                default:
+                    final String dateTime = in.nextString();
+                    return LocalDateTime.parse(dateTime, FORMATTER);
+            }
+        }
+    }
+
 }
index 2050ab0..d886da9 100644 (file)
@@ -37,6 +37,9 @@ public class SubscriptionManager {
     @Value("${vnfm-adapter.auth.password}")
     private String password;
 
+    @Value("${vnfm-adapter.base.endpoint:http://so-vnfm-adapter.onap:9092}")
+    private String baseEndpoint;
+
     @Autowired
     public SubscriptionManager(
             @Qualifier(SSL_BASED_CONFIGURABLE_REST_TEMPLATE) final RestTemplate restTemplate) {
@@ -52,7 +55,7 @@ public class SubscriptionManager {
     public InlineResponse201 createSubscription(final PkgmSubscriptionRequest pkgmSubscriptionRequest) {
         final byte[] encodedAuth = getBasicAuth(username, password);
         final String authHeader = "Basic " + new String(encodedAuth);
-        final String uri = Constant.VNFM_ADAPTER_SUBSCRIPTION_ENDPOINT;
+        final String uri = baseEndpoint + Constant.VNFM_ADAPTER_SUBSCRIPTION_ENDPOINT;
         final HttpHeaders headers = new HttpHeaders();
         headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
         headers.add(HttpHeaders.AUTHORIZATION, authHeader);
diff --git a/plans/so/integration-etsi-testing/so-simulators/vnfm-simulator/vnfm-service/src/main/java/org/onap/so/svnfm/simulator/services/providers/VnfPkgOnboardingNotificationCacheServiceProvider.java b/plans/so/integration-etsi-testing/so-simulators/vnfm-simulator/vnfm-service/src/main/java/org/onap/so/svnfm/simulator/services/providers/VnfPkgOnboardingNotificationCacheServiceProvider.java
new file mode 100644 (file)
index 0000000..b62fb86
--- /dev/null
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.svnfm.simulator.services.providers;
+
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.notification.model.VnfPackageOnboardingNotification;
+import java.util.Optional;
+
+/**
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ */
+public interface VnfPkgOnboardingNotificationCacheServiceProvider {
+
+    /**
+     * Add a VnfPkgOnboardingNotification to the cache
+     * @param vnfPkgId
+     * @param vnfPackageOnboardingNotification
+     */
+    void addVnfPkgOnboardingNotification(final String vnfPkgId, final VnfPackageOnboardingNotification vnfPackageOnboardingNotification);
+
+    /**
+     * Get a VnfPkgOnboardingNotification from the cache
+     * @param vnfPkgId
+     * @return
+     */
+    Optional<VnfPackageOnboardingNotification> getVnfPkgOnboardingNotification(final String vnfPkgId);
+}
diff --git a/plans/so/integration-etsi-testing/so-simulators/vnfm-simulator/vnfm-service/src/main/java/org/onap/so/svnfm/simulator/services/providers/VnfPkgOnboardingNotificationCacheServiceProviderImpl.java b/plans/so/integration-etsi-testing/so-simulators/vnfm-simulator/vnfm-service/src/main/java/org/onap/so/svnfm/simulator/services/providers/VnfPkgOnboardingNotificationCacheServiceProviderImpl.java
new file mode 100644 (file)
index 0000000..3f52213
--- /dev/null
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.svnfm.simulator.services.providers;
+
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.notification.model.VnfPackageOnboardingNotification;
+import org.onap.so.simulator.cache.provider.AbstractCacheServiceProvider;
+import org.onap.so.svnfm.simulator.constants.Constant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.Cache;
+import org.springframework.cache.CacheManager;
+import org.springframework.stereotype.Service;
+import java.util.Optional;
+
+/**
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ */
+@Service
+public class VnfPkgOnboardingNotificationCacheServiceProviderImpl extends AbstractCacheServiceProvider
+        implements VnfPkgOnboardingNotificationCacheServiceProvider {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(VnfPkgOnboardingNotificationCacheServiceProviderImpl.class);
+
+    @Autowired
+    public VnfPkgOnboardingNotificationCacheServiceProviderImpl(final CacheManager cacheManager) {
+        super(cacheManager);
+    }
+
+    @Override public void addVnfPkgOnboardingNotification(final String vnfPkgId,
+            final VnfPackageOnboardingNotification vnfPackageOnboardingNotification) {
+        LOGGER.debug("Adding {} to cache with vnfPkgId: {}", vnfPackageOnboardingNotification, vnfPkgId);
+        getCache(Constant.VNF_PKG_ONBOARDING_NOTIFICATION_CACHE).put(vnfPkgId, vnfPackageOnboardingNotification);
+    }
+
+    @Override public Optional<VnfPackageOnboardingNotification> getVnfPkgOnboardingNotification(final String vnfPkgId) {
+        LOGGER.debug("Getting vnfPkgOnboardingNotification from cache using vnfPkgId: {}", vnfPkgId);
+        final Cache cache = getCache(Constant.VNF_PKG_ONBOARDING_NOTIFICATION_CACHE);
+        final VnfPackageOnboardingNotification vnfPackageOnboardingNotification = cache.get(vnfPkgId, VnfPackageOnboardingNotification.class);
+        if (vnfPackageOnboardingNotification != null) {
+            return Optional.of(vnfPackageOnboardingNotification);
+        }
+        LOGGER.error("Unable to find vnfPkgOnboardingNotification in cache using vnfPkgId: {}", vnfPkgId);
+        return Optional.empty();
+    }
+}
index db2a6d4..6079a79 100644 (file)
@@ -47,6 +47,8 @@ vnfm-adapter:
    auth:
       name: vnfm
       password: password1$
+   base:
+      endpoint: http://so-vnfm-adapter.onap:9092
 vnfds:
    vnfdlist:
       -  vnfdid: 1
@@ -88,4 +90,4 @@ vnfds:
          -  vnfcid: VNFC8
             resourceTemplateId: vnfd4_vnfc6
             vduId: vnfd4_vduForVnfc6
-            type: COMPUTE
\ No newline at end of file
+            type: COMPUTE
index 743e2c0..ba8ec00 100644 (file)
@@ -31,17 +31,20 @@ import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.
 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsFilter1;
 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.notification.model.VnfPackageOnboardingNotification;
 import org.onap.so.svnfm.simulator.config.SvnfmApplication;
+import org.onap.so.svnfm.simulator.controller.SubscriptionNotificationController;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.boot.web.client.RestTemplateBuilder;
 import org.springframework.boot.web.server.LocalServerPort;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpMethod;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
+import org.springframework.http.converter.json.GsonHttpMessageConverter;
 import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.junit4.SpringRunner;
 import org.springframework.test.web.client.MockRestServiceServer;
@@ -77,6 +80,7 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat
 public class TestSubscriptionNotificationController {
 
     private static final Logger LOGGER = getLogger(TestSubscriptionNotificationController.class);
+    private static final String SOL003_SUBSCRIPTION_URL = "http://so-vnfm-adapter.onap:9092" + VNFM_ADAPTER_SUBSCRIPTION_ENDPOINT;
 
     @LocalServerPort
     private int port;
@@ -85,7 +89,6 @@ public class TestSubscriptionNotificationController {
     private RestTemplate restTemplate;
     private MockRestServiceServer mockRestServiceServer;
 
-    @Autowired
     private TestRestTemplate testRestTemplate;
 
     private Gson gson;
@@ -94,8 +97,11 @@ public class TestSubscriptionNotificationController {
     @Before
     public void setup() {
         mockRestServiceServer = MockRestServiceServer.bindTo(restTemplate).build();
-        gson = new GsonBuilder().create();
+        gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class,
+                new SubscriptionNotificationController.LocalDateTimeTypeAdapter()).create();
         vnfmSimulatorCallbackUrl = getBaseUrl(port) + PACKAGE_MANAGEMENT_BASE_URL + NOTIFICATION_ENDPOINT;
+        testRestTemplate = new TestRestTemplate(
+                new RestTemplateBuilder().additionalMessageConverters(new GsonHttpMessageConverter(gson)));
     }
 
     @After
@@ -118,7 +124,7 @@ public class TestSubscriptionNotificationController {
                 new InlineResponse201().id("subscriptionId").filter(new SubscriptionsFilter1())
                         .callbackUri("callbackUri");
 
-        mockRestServiceServer.expect(requestTo(VNFM_ADAPTER_SUBSCRIPTION_ENDPOINT)).andExpect(method(HttpMethod.POST))
+        mockRestServiceServer.expect(requestTo(SOL003_SUBSCRIPTION_URL)).andExpect(method(HttpMethod.POST))
                 .andExpect(content().json(gson.toJson(pkgmSubscriptionRequest)))
                 .andRespond(withSuccess(gson.toJson(inlineResponse), APPLICATION_JSON));
 
@@ -137,7 +143,7 @@ public class TestSubscriptionNotificationController {
                 new InlineResponse201().id("subscriptionId").filter(new SubscriptionsFilter1())
                         .callbackUri("callbackUri");
 
-        mockRestServiceServer.expect(requestTo(VNFM_ADAPTER_SUBSCRIPTION_ENDPOINT)).andExpect(method(HttpMethod.POST))
+        mockRestServiceServer.expect(requestTo(SOL003_SUBSCRIPTION_URL)).andExpect(method(HttpMethod.POST))
                 .andExpect(content().json(gson.toJson(pkgmSubscriptionRequest)))
                 .andRespond(withSuccess(gson.toJson(inlineResponse), APPLICATION_JSON));
 
@@ -152,8 +158,6 @@ public class TestSubscriptionNotificationController {
         final VnfPackageOnboardingNotification vnfPackageOnboardingNotification =
                 gson.fromJson(getNotification(VNFPACKAGEONBOARDINGNOTIFICATION),
                         VnfPackageOnboardingNotification.class);
-        final LocalDateTime timestamp = LocalDateTime.of(2020, 1, 1, 1, 1, 1, 1);
-        vnfPackageOnboardingNotification.setTimeStamp(timestamp);
         final ResponseEntity<?> responseEntity = postNotification(vnfPackageOnboardingNotification);
         assertEquals(HttpStatus.NO_CONTENT, responseEntity.getStatusCode());
     }
index 17e2807..249010a 100644 (file)
@@ -1,5 +1,7 @@
 # Test suites are relative paths under [integration/csit.git]/tests/.
 # Place the suites in run order.
+so/etsi/etsi_vnf_subscription_tests.robot
 so/etsi/etsi_package_onboarding_tests.robot
 so/etsi/etsi_vnf_lcm_tests.robot
 so/etsi/etsi_vnf_package_management_tests.robot
+so/etsi/etsi_vnf_notification_tests.robot
index c841956..41eeb8b 100644 (file)
   "operationalState": "ENABLED",
   "_links": {
     "self": {
-      "href": "http://so-vnfm-adapter:9092/so/vnfm-adapter/v1/vnfpkgm/v1/vnf_packages/73522444-e8e9-49c1-be29-d355800aa349"
+      "href": "http://so-vnfm-adapter.onap:9092/so/vnfm-adapter/v1/vnfpkgm/v1/vnf_packages/73522444-e8e9-49c1-be29-d355800aa349"
     },
     "vnfd": {
-      "href": "http://so-vnfm-adapter:9092/so/vnfm-adapter/v1/vnfpkgm/v1/vnf_packages/73522444-e8e9-49c1-be29-d355800aa349/vnfd"
+      "href": "http://so-vnfm-adapter.onap:9092/so/vnfm-adapter/v1/vnfpkgm/v1/vnf_packages/73522444-e8e9-49c1-be29-d355800aa349/vnfd"
     },
     "packageContent": {
-      "href": "http://so-vnfm-adapter:9092/so/vnfm-adapter/v1/vnfpkgm/v1/vnf_packages/73522444-e8e9-49c1-be29-d355800aa349/package_content"
+      "href": "http://so-vnfm-adapter.onap:9092/so/vnfm-adapter/v1/vnfpkgm/v1/vnf_packages/73522444-e8e9-49c1-be29-d355800aa349/package_content"
     }
   }
 }
diff --git a/tests/so/etsi/data/subscriptionRequest.json b/tests/so/etsi/data/subscriptionRequest.json
new file mode 100644 (file)
index 0000000..c54bf3c
--- /dev/null
@@ -0,0 +1,23 @@
+{
+  "filter": {
+    "notificationTypes": [
+      "VnfPackageOnboardingNotification",
+      "VnfPackageChangeNotification"
+    ],
+    "vnfdId": [
+      "b1bb0ce7-2222-4fa7-95ed-4840d70a1177"
+    ],
+    "operationalState": ["ENABLED", "DISABLED"]
+  },
+  "callbackUri": "http://so-vnfm-simulator:9093/vnfpkgm/v1/notification",
+  "authentication": {
+    "authType": [
+      "OAUTH2_CLIENT_CREDENTIALS"
+    ],
+    "paramsOauth2ClientCredentials": {
+      "clientId": "vnfm",
+      "clientPassword": "password1$",
+      "tokenEndpoint": "http://so-vnfm-simulator:9093/oauth/token?grant_type=client_credentials"
+    }
+  }
+}
diff --git a/tests/so/etsi/etsi_vnf_notification_tests.robot b/tests/so/etsi/etsi_vnf_notification_tests.robot
new file mode 100644 (file)
index 0000000..0d1eb41
--- /dev/null
@@ -0,0 +1,44 @@
+*** Settings ***
+Library     Collections
+Library     RequestsLibrary
+Library     OperatingSystem
+Library     json
+
+*** Variables ***
+${SLEEP_INTERVAL_SEC}=   5
+${MAXIMUM_ATTEMPTS_BEFORE_TIMEOUT}=     48     # Represents the maximum number of attempts that will be made before a timeout. It sleeps for SLEEP_INTERVAL_SEC seconds before retry.
+${PACKAGE_MANAGEMENT_BASE_URL}=    /so/vnfm-adapter/v1/vnfpkgm/v1
+${BASIC_AUTH}=    Basic dm5mbTpwYXNzd29yZDEk
+${VNF_PACKAGE_ID}=    73522444-e8e9-49c1-be29-d355800aa349
+
+*** Test Cases ***
+VNF Package Onboarding Notification Received By Subscriber
+    &{headers}=    Create Dictionary    Authorization=Bearer ${ACCESS_TOKEN}    Content-Type=application/json    Accept=application/json
+    Log To Console    \nChecking If VNF Package Notification was received for vnfPkgId: ${VNF_PACKAGE_ID}
+    ${response}=    Get On Session    vnfm_simulator_session    /vnfpkgm/v1/notification-cache-test/${VNF_PACKAGE_ID}    headers=${headers}
+    Log To Console    \nResponse:${response}
+    Run Keyword If    '${response.status_code}' == '200'    Log To Console    \nexecuted with expected result
+    Should Be Equal As Strings    '${response.status_code}'    '200'
+    Log To Console    \nResponse Content:\n${response.content}
+    ${json_response}=    Evaluate    json.loads(r"""${response.content}""", strict=False)    json
+    Dictionary Should Contain Key        ${json_response}    id
+    Dictionary Should Contain Key        ${json_response}    notificationType
+    Should be Equal As Strings    VnfPackageOnboardingNotification    ${json_response}[notificationType]
+    Dictionary Should Contain Key        ${json_response}    subscriptionId
+    Dictionary Should Contain Key        ${json_response}    timeStamp
+    Dictionary Should Contain Key        ${json_response}    vnfPkgId
+    Should Be Equal As Strings    ${VNF_PACKAGE_ID}    ${json_response}[vnfPkgId]
+    Dictionary Should Contain Key        ${json_response}    vnfdId
+    Dictionary Should Contain Key        ${json_response}    _links
+    Log To Console    \nexecuted with expected result
+
+Delete Subscription By SubscriptionId
+    Create Session    so_vnfm_adapter_session    http://${REPO_IP}:9092
+    &{headers}=    Create Dictionary    Authorization=${BASIC_AUTH}    Content-Type=application/json    Accept=application/json
+    Log To Console    \nDeleting Subscription with subscriptionId: ${SUBSCRIPTION_ID} from so-vnfm-adapter
+    ${response}=    Delete On Session    so_vnfm_adapter_session    ${PACKAGE_MANAGEMENT_BASE_URL}/subscriptions/${SUBSCRIPTION_ID}    headers=${headers}
+    Log To Console    \nResponse:${response}
+    Run Keyword If    '${response.status_code}' == '204'    Log To Console    \nexecuted with expected result
+    Should Be Equal As Strings    '${response.status_code}'    '204'
+
+
diff --git a/tests/so/etsi/etsi_vnf_subscription_tests.robot b/tests/so/etsi/etsi_vnf_subscription_tests.robot
new file mode 100644 (file)
index 0000000..3bf2262
--- /dev/null
@@ -0,0 +1,89 @@
+*** Settings ***
+Library     Collections
+Library     RequestsLibrary
+Library     OperatingSystem
+Library     json
+
+*** Variables ***
+${SLEEP_INTERVAL_SEC}=   5
+${MAXIMUM_ATTEMPTS_BEFORE_TIMEOUT}=     48     # Represents the maximum number of attempts that will be made before a timeout. It sleeps for SLEEP_INTERVAL_SEC seconds before retry.
+${PACKAGE_MANAGEMENT_BASE_URL}=    /so/vnfm-adapter/v1/vnfpkgm/v1
+${BASIC_AUTH}=    Basic dm5mbTpwYXNzd29yZDEk
+${ACCESS_TOKEN}=    ""
+${SUBSCRIPTION_ID}=    ""
+
+*** Test Cases ***
+Subscribe for Notifications
+    Create Session    vnfm_simulator_session    http://${REPO_IP}:9093
+    &{headers1}=    Create Dictionary    Authorization=${BASIC_AUTH}    Content-Type=application/json    Accept=application/json
+    Log To Console    \nGetting Access Token
+    ${response}=    Post On Session    vnfm_simulator_session    url=/oauth/token?grant_type=client_credentials    headers=${headers1}
+    Log To Console    \nResponse:${response}
+    Run Keyword If    '${response.status_code}' == '200'    Log To Console    \nexecuted with expected result
+    Should Be Equal As Strings    '${response.status_code}'    '200'
+    Log To Console    \nResponse Content:\n${response.content}
+    ${json_response}    Evaluate    json.loads(r"""${response.content}""", strict=False)    json
+    Set Global Variable    ${ACCESS_TOKEN}    ${json_response}[access_token]
+    ${data}=    Get Binary File     ${CURDIR}${/}data${/}subscriptionRequest.json
+    &{headers2}=    Create Dictionary    Authorization=Bearer ${ACCESS_TOKEN}    Content-Type=application/json    Accept=application/json
+    Log To Console    \nSubscribing For VNF Package Notifications
+    ${response2}=    Post On Session    vnfm_simulator_session    /vnfpkgm/v1/subscribe    data=${data}    headers=${headers2}
+    Log To Console    \nResponse:\n${response2}
+    Log To Console    \nResponse Content:\n${response2.content}
+    Run Keyword If    '${response2.status_code}' == '200'    Log To Console    \nexecuted with expected result
+    Should Be Equal As Strings    '${response2.status_code}'    '200'
+    ${json_response2}=    Evaluate    json.loads(r"""${response2.content}""", strict=False)    json
+    Dictionary Should Contain Key    ${json_response2}    id
+    Set Global Variable    ${SUBSCRIPTION_ID}    ${json_response2}[id]
+    Log To Console    \nid: ${SUBSCRIPTION_ID}
+    Dictionary Should Contain Key    ${json_response2}    filter
+    ${filter}=    Set Variable    ${json_response2}[filter]
+    Dictionary Should Contain Key    ${filter}    notificationTypes
+    Dictionary Should Contain Key    ${filter}    vnfdId
+    Dictionary Should Contain Key    ${filter}    operationalState
+    Dictionary Should Contain Key    ${json_response2}    callbackUri
+    Dictionary Should Contain Key    ${json_response2}    _links
+    Log To Console    \nexecuted with expected result
+
+Get Subscriptions
+    Create Session    so_vnfm_adapter_session    http://${REPO_IP}:9092
+    &{headers}=    Create Dictionary    Authorization=${BASIC_AUTH}    Content-Type=application/json    Accept=application/json
+    Log To Console    \nGetting Subscriptions from so-vnfm-adapter
+    ${response}=    Get On Session    so_vnfm_adapter_session    ${PACKAGE_MANAGEMENT_BASE_URL}/subscriptions    headers=${headers}
+    Log To Console    \nResponse:${response}
+    Run Keyword If    '${response.status_code}' == '200'    Log To Console    \nexecuted with expected result
+    Should Be Equal As Strings    '${response.status_code}'    '200'
+    Log To Console    \nResponse Content:\n${response.content}
+    ${json_response}    Evaluate    json.loads(r"""${response.content}""", strict=False)    json
+    ${subscription}=    Set Variable    ${json_response}[0]
+    Dictionary Should Contain Key    ${subscription}    id
+    ${sub_id}=    Set Variable    ${subscription}[id]
+    Should Be Equal As Strings    '${sub_id}'    '${SUBSCRIPTION_ID}'
+    Dictionary Should Contain Key    ${subscription}    filter
+    ${filter}=    Set Variable    ${subscription}[filter]
+    Dictionary Should Contain Key    ${filter}    notificationTypes
+    Dictionary Should Contain Key    ${filter}    vnfdId
+    Dictionary Should Contain Key    ${filter}    operationalState
+    Dictionary Should Contain Key    ${subscription}    callbackUri
+    Log To Console    \nexecuted with expected result
+
+Get Subscription By Subscription Id
+    Create Session    so_vnfm_adapter_session    http://${REPO_IP}:9092
+    &{headers}=    Create Dictionary    Authorization=${BASIC_AUTH}    Content-Type=application/json    Accept=application/json
+    Log To Console    \nGetting Subscription with id ${SUBSCRIPTION_ID} from so-vnfm-adapter
+    ${response}=    Get On Session    so_vnfm_adapter_session    ${PACKAGE_MANAGEMENT_BASE_URL}/subscriptions/${SUBSCRIPTION_ID}    headers=${headers}
+    Log To Console    \nResponse:${response}
+    Run Keyword If    '${response.status_code}' == '200'    Log To Console    \nexecuted with expected result
+    Should Be Equal As Strings    '${response.status_code}'    '200'
+    Log To Console    \nResponse Content:\n${response.content}
+    ${json_response}    Evaluate    json.loads(r"""${response.content}""", strict=False)    json
+    Dictionary Should Contain Key    ${json_response}    id
+    ${sub_id}=    Set Variable    ${json_response}[id]
+    Should Be Equal As Strings    '${sub_id}'    '${SUBSCRIPTION_ID}'
+    Dictionary Should Contain Key    ${json_response}    filter
+    ${filter}=    Set Variable    ${json_response}[filter]
+    Dictionary Should Contain Key    ${filter}    notificationTypes
+    Dictionary Should Contain Key    ${filter}    vnfdId
+    Dictionary Should Contain Key    ${filter}    operationalState
+    Dictionary Should Contain Key    ${json_response}    callbackUri
+    Log To Console    \nexecuted with expected result