2  * ============LICENSE_START=======================================================
 
   3  *  Copyright (C) 2020 Nordix Foundation.
 
   4  * ================================================================================
 
   5  * Licensed under the Apache License, Version 2.0 (the "License");
 
   6  * you may not use this file except in compliance with the License.
 
   7  * You may obtain a copy of the License at
 
   9  *      http://www.apache.org/licenses/LICENSE-2.0
 
  11  * Unless required by applicable law or agreed to in writing, software
 
  12  * distributed under the License is distributed on an "AS IS" BASIS,
 
  13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  14  * See the License for the specific language governing permissions and
 
  15  * limitations under the License.
 
  17  * SPDX-License-Identifier: Apache-2.0
 
  18  * ============LICENSE_END=========================================================
 
  21 package org.onap.so.adapters.etsisol003adapter.pkgm.rest;
 
  23 import static org.junit.Assert.assertEquals;
 
  24 import static org.junit.Assert.assertTrue;
 
  25 import static org.onap.so.adapters.etsi.sol003.adapter.common.CommonConstants.ETSI_SUBSCRIPTION_NOTIFICATION_CONTROLLER_BASE_URL;
 
  26 import static org.onap.so.client.RestTemplateConfig.CONFIGURABLE_REST_TEMPLATE;
 
  27 import static org.springframework.test.annotation.DirtiesContext.ClassMode.BEFORE_CLASS;
 
  28 import static org.springframework.test.web.client.match.MockRestRequestMatchers.header;
 
  29 import static org.springframework.test.web.client.match.MockRestRequestMatchers.jsonPath;
 
  30 import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
 
  31 import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
 
  32 import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
 
  33 import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
 
  35 import java.time.LocalDateTime;
 
  36 import java.util.ArrayList;
 
  37 import java.util.List;
 
  38 import java.util.UUID;
 
  39 import org.junit.After;
 
  40 import org.junit.Before;
 
  41 import org.junit.Test;
 
  42 import org.junit.runner.RunWith;
 
  43 import org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model.NOTIFICATIONLINKSERIALIZER;
 
  44 import org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model.PkgChangeNotification;
 
  45 import org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model.PkgOnboardingNotification;
 
  46 import org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model.PkgmLinks;
 
  47 import org.onap.so.adapters.etsisol003adapter.pkgm.JSON;
 
  48 import org.onap.so.adapters.etsisol003adapter.pkgm.PackageManagementConstants;
 
  49 import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.ProblemDetails;
 
  50 import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.vnfm.notification.model.VnfPackageChangeNotification;
 
  51 import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.vnfm.notification.model.VnfPackageOnboardingNotification;
 
  52 import org.onap.so.adapters.etsisol003adapter.pkgm.model.PkgmSubscriptionRequest;
 
  53 import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthentication;
 
  54 import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthenticationParamsBasic;
 
  55 import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthenticationParamsOauth2ClientCredentials;
 
  56 import org.onap.so.configuration.rest.BasicHttpHeadersProvider;
 
  57 import org.springframework.beans.factory.annotation.Autowired;
 
  58 import org.springframework.beans.factory.annotation.Qualifier;
 
  59 import org.springframework.boot.test.context.SpringBootTest;
 
  60 import org.springframework.boot.test.web.client.TestRestTemplate;
 
  61 import org.springframework.boot.web.client.RestTemplateBuilder;
 
  62 import org.springframework.boot.web.server.LocalServerPort;
 
  63 import org.springframework.cache.Cache;
 
  64 import org.springframework.cache.CacheManager;
 
  65 import org.springframework.http.HttpEntity;
 
  66 import org.springframework.http.HttpMethod;
 
  67 import org.springframework.http.HttpStatus;
 
  68 import org.springframework.http.MediaType;
 
  69 import org.springframework.http.ResponseEntity;
 
  70 import org.springframework.http.converter.json.GsonHttpMessageConverter;
 
  71 import org.springframework.test.annotation.DirtiesContext;
 
  72 import org.springframework.test.context.ActiveProfiles;
 
  73 import org.springframework.test.context.junit4.SpringRunner;
 
  74 import org.springframework.test.web.client.MockRestServiceServer;
 
  75 import org.springframework.web.client.RestTemplate;
 
  76 import com.google.gson.Gson;
 
  79  * @author Andrew Lamb (andrew.a.lamb@est.tech)
 
  82 @RunWith(SpringRunner.class)
 
  83 @SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
 
  84 @ActiveProfiles("test")
 
  85 @DirtiesContext(classMode = BEFORE_CLASS)
 
  86 public class EtsiSubscriptionNotificationControllerTest {
 
  91     private static final URI CALLBACK_URI = URI.create("http://test_callback_uri/notification");
 
  92     private static final String TOKEN_ENDPOINT = "http://test_token_endpoint_uri/";
 
  93     private static final String TOKEN = "dXNlcm5hbWU6cGFzc3dvcmQ=......";
 
  94     private static final String JSON_TOKEN = "{\"access_token\":\"" + TOKEN + "\"}";
 
  95     private static final String LOCALHOST_URL = "http://localhost:";
 
  96     private static final String NOTIFICATION_BASE_URL =
 
  97             ETSI_SUBSCRIPTION_NOTIFICATION_CONTROLLER_BASE_URL + "/notification";
 
  98     private static final String USERNAME = "username";
 
  99     private static final String PASSWORD = "password";
 
 100     private static final String EXPECTED_BASIC_AUTHORIZATION = "Basic dXNlcm5hbWU6cGFzc3dvcmQ=";
 
 101     private static final String EXPECTED_OAUTH_AUTHORIZATION = "Bearer " + TOKEN;
 
 102     private static final String NOTIFICATION_ID = "NOTIFICATION_ID";
 
 103     private static final String SUBSCRIPTION_ID = "SUBSCRIPTION_ID";
 
 104     private static final String TIME_STAMP_STRING_EXPECTED_FROM_ETSI_CATALOG = "2020-01-01 01:01:01";
 
 105     private static final java.time.LocalDateTime TIMESTAMP = java.time.LocalDateTime.of(2020, 1, 1, 1, 1, 1, 1);
 
 106     private static final String VNFPKG_ID = UUID.randomUUID().toString();
 
 107     private static final String VNFD_ID = UUID.randomUUID().toString();
 
 108     private static final String EXPECTED_VNF_PACKAGE_HREF =
 
 109             "https://so-vnfm-adapter.onap:30406/so/vnfm-adapter/v1/vnfpkgm/v1/vnf_packages/" + VNFPKG_ID;
 
 110     private static final String EXPECTED_SUBSCRIPTION_HREF =
 
 111             "https://so-vnfm-adapter.onap:30406/so/vnfm-adapter/v1/vnfpkgm/v1/subscriptions/" + SUBSCRIPTION_ID;
 
 114     private BasicHttpHeadersProvider basicHttpHeadersProvider;
 
 117     @Qualifier(CONFIGURABLE_REST_TEMPLATE)
 
 118     private RestTemplate restTemplate;
 
 119     private MockRestServiceServer mockRestServiceServer;
 
 121     private TestRestTemplate testRestTemplate;
 
 124     private CacheManager cacheServiceProvider;
 
 128     public void setUp() {
 
 129         mockRestServiceServer = MockRestServiceServer.bindTo(restTemplate).build();
 
 130         basicHttpHeadersProvider = new BasicHttpHeadersProvider();
 
 131         cache = cacheServiceProvider.getCache(PackageManagementConstants.PACKAGE_MANAGEMENT_SUBSCRIPTION_CACHE);
 
 134         final Gson gson = JSON.createGson().registerTypeAdapter(LocalDateTime.class,
 
 135                 new EtsiSubscriptionNotificationController.LocalDateTimeTypeAdapter()).create();
 
 136         testRestTemplate = new TestRestTemplate(
 
 137                 new RestTemplateBuilder().additionalMessageConverters(new GsonHttpMessageConverter(gson)));
 
 142     public void tearDown() {
 
 143         mockRestServiceServer.reset();
 
 148     public void testSubscriptionNotificationEndPoint_ReturnsNoContent() {
 
 149         final ResponseEntity<?> response = sendHttpGet(NOTIFICATION_BASE_URL);
 
 150         assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
 
 154     public void testOnboardingNotificationSentOnToVnfmCallbackUri_SubscriptionRequestInCache_Success() {
 
 155         final PkgmSubscriptionRequest subscriptionRequest =
 
 156                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
 
 157         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
 
 158         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
 
 160         mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
 
 161                 .andExpect(jsonPath("$.id").value(NOTIFICATION_ID))
 
 162                 .andExpect(jsonPath("$.notificationType")
 
 163                         .value(VnfPackageOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION
 
 165                 .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID))
 
 166                 .andExpect(jsonPath("$.timeStamp").value(TIME_STAMP_STRING_EXPECTED_FROM_ETSI_CATALOG))
 
 167                 .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID)).andExpect(jsonPath("$.vnfdId").value(VNFD_ID))
 
 168                 .andExpect(jsonPath("$._links")
 
 169                         .value(buildPkgmLinks(EXPECTED_VNF_PACKAGE_HREF, EXPECTED_SUBSCRIPTION_HREF)))
 
 170                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess());
 
 172         final ResponseEntity<?> response = sendHttpPost(notification);
 
 174         assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
 
 178     public void testOnboardingNotificationNotSentOnToVnfmCallbackUri_SubscriptionRequestNotInCache_Fail() {
 
 179         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
 
 180         final ResponseEntity<?> response = sendHttpPost(notification);
 
 182         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
 
 183         assertTrue(response.getBody() instanceof ProblemDetails);
 
 185         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
 
 186         final String errorMessage = "No subscription found with subscriptionId " + SUBSCRIPTION_ID
 
 187                 + ". Unable to forward notification to subscriber.";
 
 189         assertEquals(errorMessage, problemDetails.getDetail());
 
 193     public void testOnboardingNotificationSentOnToVnfmCallbackUri_BadRequestResponseFromCallbackUri_Fail() {
 
 194         final PkgmSubscriptionRequest subscriptionRequest =
 
 195                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
 
 196         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
 
 197         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
 
 199         mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
 
 200                 .andRespond(withStatus(HttpStatus.BAD_REQUEST));
 
 202         final ResponseEntity<?> response = sendHttpPost(notification);
 
 204         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
 
 205         assertTrue(response.getBody() instanceof ProblemDetails);
 
 207         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
 
 208         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
 
 209                 + HttpStatus.BAD_REQUEST + ".\n" + "No result found for given url: " + CALLBACK_URI;
 
 211         assertEquals(errorMessage, problemDetails.getDetail());
 
 215     public void testOnboardingNotificationSentOnToVnfmCallbackUri_301MovedPermanentlyResponseFromCallbackUri_Fail() {
 
 216         final PkgmSubscriptionRequest subscriptionRequest =
 
 217                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
 
 218         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
 
 219         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
 
 221         mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
 
 222                 .andRespond(withStatus(HttpStatus.MOVED_PERMANENTLY));
 
 224         final ResponseEntity<?> response = sendHttpPost(notification);
 
 226         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
 
 227         assertTrue(response.getBody() instanceof ProblemDetails);
 
 229         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
 
 230         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed.";
 
 232         assertEquals(errorMessage, problemDetails.getDetail());
 
 236     public void testOnboardingNotificationSentOnToVnfmCallbackUri_NotFoundResponseFromCallbackUri_Fail() {
 
 237         final PkgmSubscriptionRequest subscriptionRequest =
 
 238                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
 
 239         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
 
 240         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
 
 242         mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
 
 243                 .andRespond(withStatus(HttpStatus.NOT_FOUND));
 
 245         final ResponseEntity<?> response = sendHttpPost(notification);
 
 247         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
 
 248         assertTrue(response.getBody() instanceof ProblemDetails);
 
 250         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
 
 251         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
 
 252                 + HttpStatus.NOT_FOUND + ".\n" + "No result found for given url: " + CALLBACK_URI;
 
 254         assertEquals(errorMessage, problemDetails.getDetail());
 
 258     public void testOnboardingNotificationSentOnToVnfmCallbackUri_InternalServerErrorResponseFromCallbackUri_Fail() {
 
 259         final PkgmSubscriptionRequest subscriptionRequest =
 
 260                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
 
 261         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
 
 262         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
 
 264         mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
 
 265                 .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
 
 267         final ResponseEntity<?> response = sendHttpPost(notification);
 
 269         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
 
 270         assertTrue(response.getBody() instanceof ProblemDetails);
 
 272         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
 
 273         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
 
 274                 + HttpStatus.INTERNAL_SERVER_ERROR.value() + ".\n" + "Unable to invoke HTTP POST using URL: "
 
 277         assertEquals(errorMessage, problemDetails.getDetail());
 
 281     public void testChangeNotificationSentOnToVnfmCallbackUri_SubscriptionRequestInCache_Success() {
 
 282         final PkgmSubscriptionRequest subscriptionRequest =
 
 283                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
 
 284         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
 
 285         final PkgChangeNotification notification = buildPkgChangeNotification();
 
 287         mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
 
 288                 .andExpect(jsonPath("$.id").value(NOTIFICATION_ID))
 
 289                 .andExpect(jsonPath("$.notificationType").value(
 
 290                         VnfPackageChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION.getValue()))
 
 291                 .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID))
 
 292                 .andExpect(jsonPath("$.timeStamp").value(TIME_STAMP_STRING_EXPECTED_FROM_ETSI_CATALOG))
 
 293                 .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID)).andExpect(jsonPath("$.vnfdId").value(VNFD_ID))
 
 295                         jsonPath("$.changeType").value(PkgChangeNotification.ChangeTypeEnum.OP_STATE_CHANGE.toString()))
 
 296                 .andExpect(jsonPath("$.operationalState")
 
 297                         .value(PkgChangeNotification.OperationalStateEnum.ENABLED.toString()))
 
 298                 .andExpect(jsonPath("$._links")
 
 299                         .value(buildPkgmLinks(EXPECTED_VNF_PACKAGE_HREF, EXPECTED_SUBSCRIPTION_HREF)))
 
 300                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess());
 
 302         final ResponseEntity<?> response = sendHttpPost(notification);
 
 304         assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
 
 308     public void testChangeNotificationNotSentOnToVnfmCallbackUri_SubscriptionRequestNotInCache_Fail() {
 
 309         final PkgChangeNotification notification = buildPkgChangeNotification();
 
 310         final ResponseEntity<?> response = sendHttpPost(notification);
 
 312         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
 
 313         assertTrue(response.getBody() instanceof ProblemDetails);
 
 315         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
 
 316         final String errorMessage = "No subscription found with subscriptionId " + SUBSCRIPTION_ID
 
 317                 + ". Unable to forward notification to subscriber.";
 
 319         assertEquals(errorMessage, problemDetails.getDetail());
 
 323     public void testChangeNotificationSentOnToVnfmCallbackUri_BadRequestResponseFromCallbackUri_Fail() {
 
 324         final PkgmSubscriptionRequest subscriptionRequest =
 
 325                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
 
 326         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
 
 327         final PkgChangeNotification notification = buildPkgChangeNotification();
 
 329         mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
 
 330                 .andRespond(withStatus(HttpStatus.BAD_REQUEST));
 
 332         final ResponseEntity<?> response = sendHttpPost(notification);
 
 334         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
 
 335         assertTrue(response.getBody() instanceof ProblemDetails);
 
 337         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
 
 338         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
 
 339                 + HttpStatus.BAD_REQUEST + ".\n" + "No result found for given url: " + CALLBACK_URI;
 
 341         assertEquals(errorMessage, problemDetails.getDetail());
 
 345     public void testChangeNotificationSentOnToVnfmCallbackUri_NotFoundResponseFromCallbackUri_Fail() {
 
 346         final PkgmSubscriptionRequest subscriptionRequest =
 
 347                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
 
 348         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
 
 349         final PkgChangeNotification notification = buildPkgChangeNotification();
 
 351         mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
 
 352                 .andRespond(withStatus(HttpStatus.NOT_FOUND));
 
 354         final ResponseEntity<?> response = sendHttpPost(notification);
 
 356         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
 
 357         assertTrue(response.getBody() instanceof ProblemDetails);
 
 359         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
 
 360         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
 
 361                 + HttpStatus.NOT_FOUND + ".\n" + "No result found for given url: " + CALLBACK_URI;
 
 363         assertEquals(errorMessage, problemDetails.getDetail());
 
 367     public void testChangeNotificationSentOnToVnfmCallbackUri_InternalServerErrorResponseFromCallbackUri_Fail() {
 
 368         final PkgmSubscriptionRequest subscriptionRequest =
 
 369                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
 
 370         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
 
 371         final PkgChangeNotification notification = buildPkgChangeNotification();
 
 373         mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
 
 374                 .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
 
 376         final ResponseEntity<?> response = sendHttpPost(notification);
 
 378         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
 
 379         assertTrue(response.getBody() instanceof ProblemDetails);
 
 381         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
 
 382         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
 
 383                 + HttpStatus.INTERNAL_SERVER_ERROR.value() + ".\n" + "Unable to invoke HTTP POST using URL: "
 
 386         assertEquals(errorMessage, problemDetails.getDetail());
 
 390     public void testNotificationSentOnToVnfm_BasicAuthUserPasswordAuthorized_Success() {
 
 391         final PkgmSubscriptionRequest subscriptionRequest =
 
 392                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
 
 393         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
 
 394         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
 
 396         mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
 
 397                 .andExpect(jsonPath("$.id").value(NOTIFICATION_ID))
 
 398                 .andExpect(jsonPath("$.notificationType")
 
 399                         .value(VnfPackageOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION
 
 401                 .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID))
 
 402                 .andExpect(jsonPath("$.timeStamp").value(TIME_STAMP_STRING_EXPECTED_FROM_ETSI_CATALOG))
 
 403                 .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID)).andExpect(jsonPath("$.vnfdId").value(VNFD_ID))
 
 404                 .andExpect(jsonPath("$._links")
 
 405                         .value(buildPkgmLinks(EXPECTED_VNF_PACKAGE_HREF, EXPECTED_SUBSCRIPTION_HREF)))
 
 406                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess());
 
 408         final ResponseEntity<?> response = sendHttpPost(notification);
 
 410         assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
 
 414     public void testNotificationSentOnToVnfm_BasicAuthUserPasswordNotAuthorized_Fail() {
 
 415         final PkgmSubscriptionRequest subscriptionRequest =
 
 416                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
 
 417         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
 
 418         final PkgChangeNotification notification = buildPkgChangeNotification();
 
 420         mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
 
 421                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION))
 
 422                 .andRespond(withStatus(HttpStatus.UNAUTHORIZED));
 
 424         final ResponseEntity<?> response = sendHttpPost(notification);
 
 426         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
 
 427         assertTrue(response.getBody() instanceof ProblemDetails);
 
 429         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
 
 430         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
 
 431                 + HttpStatus.UNAUTHORIZED.value() + ".\n" + "Unable to invoke HTTP POST using URL: " + CALLBACK_URI;
 
 433         assertEquals(errorMessage, problemDetails.getDetail());
 
 437     public void testNotificationSentOnToVnfm_OAuthAuthorized_Success() {
 
 438         final PkgmSubscriptionRequest subscriptionRequest =
 
 439                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS);
 
 440         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
 
 441         final PkgChangeNotification notification = buildPkgChangeNotification();
 
 443         mockRestServiceServer.expect(requestTo(TOKEN_ENDPOINT)).andExpect(method(HttpMethod.POST))
 
 444                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION))
 
 445                 .andRespond(withSuccess(JSON_TOKEN, MediaType.APPLICATION_JSON));
 
 447         mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
 
 448                 .andExpect(header("Authorization", EXPECTED_OAUTH_AUTHORIZATION))
 
 449                 .andExpect(jsonPath("$.id").value(NOTIFICATION_ID))
 
 450                 .andExpect(jsonPath("$.notificationType").value(
 
 451                         VnfPackageChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION.toString()))
 
 452                 .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID))
 
 453                 .andExpect(jsonPath("$.timeStamp").value(TIME_STAMP_STRING_EXPECTED_FROM_ETSI_CATALOG))
 
 454                 .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID)).andExpect(jsonPath("$.vnfdId").value(VNFD_ID))
 
 456                         jsonPath("$.changeType").value(PkgChangeNotification.ChangeTypeEnum.OP_STATE_CHANGE.toString()))
 
 457                 .andExpect(jsonPath("$.operationalState")
 
 458                         .value(PkgChangeNotification.OperationalStateEnum.ENABLED.toString()))
 
 459                 .andExpect(jsonPath("$._links")
 
 460                         .value(buildPkgmLinks(EXPECTED_VNF_PACKAGE_HREF, EXPECTED_SUBSCRIPTION_HREF)))
 
 461                 .andRespond(withSuccess());
 
 463         final ResponseEntity<?> response = sendHttpPost(notification);
 
 465         assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
 
 469     public void testNotificationSentOnToVnfm_OAuthTokenNotReceived_Fail() {
 
 470         final PkgmSubscriptionRequest subscriptionRequest =
 
 471                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS);
 
 472         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
 
 473         final PkgChangeNotification notification = buildPkgChangeNotification();
 
 475         mockRestServiceServer.expect(requestTo(TOKEN_ENDPOINT)).andExpect(method(HttpMethod.POST))
 
 476                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess());
 
 478         final ResponseEntity<?> response = sendHttpPost(notification);
 
 480         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
 
 481         assertTrue(response.getBody() instanceof ProblemDetails);
 
 483         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
 
 484         final String errorMessage = "An error occurred.  Unable to retrieve OAuth Token from VNFM for notification.";
 
 486         assertEquals(errorMessage, problemDetails.getDetail());
 
 490     public void testNotificationSentOnToVnfm_TLSCertNotYetSupported_Fail() {
 
 491         final PkgmSubscriptionRequest subscriptionRequest =
 
 492                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.TLS_CERT);
 
 493         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
 
 494         final PkgChangeNotification notification = buildPkgChangeNotification();
 
 496         final ResponseEntity<?> response = sendHttpPost(notification);
 
 498         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
 
 499         assertTrue(response.getBody() instanceof ProblemDetails);
 
 501         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
 
 502         final String errorMessage = "An error occurred.  Authentication type "
 
 503                 + subscriptionRequest.getAuthentication().getAuthType().toString() + " not currently supported.";
 
 505         assertEquals(errorMessage, problemDetails.getDetail());
 
 508     private PkgOnboardingNotification buildPkgOnboardingNotification() {
 
 509         final PkgOnboardingNotification notification = new PkgOnboardingNotification();
 
 510         notification.setId(NOTIFICATION_ID);
 
 512                 .setNotificationType(PkgOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION);
 
 513         notification.setSubscriptionId(SUBSCRIPTION_ID);
 
 514         notification.setTimeStamp(TIMESTAMP);
 
 515         notification.setVnfPkgId(VNFPKG_ID);
 
 516         notification.setVnfdId(VNFD_ID);
 
 517         notification.setLinks(buildPkgmLinks());
 
 521     private PkgChangeNotification buildPkgChangeNotification() {
 
 522         final PkgChangeNotification notification = new PkgChangeNotification();
 
 523         notification.setId(NOTIFICATION_ID);
 
 524         notification.setNotificationType(PkgChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION);
 
 525         notification.setSubscriptionId(SUBSCRIPTION_ID);
 
 526         notification.setTimeStamp(TIMESTAMP);
 
 527         notification.setVnfPkgId(VNFPKG_ID);
 
 528         notification.setVnfdId(VNFD_ID);
 
 529         notification.setChangeType(PkgChangeNotification.ChangeTypeEnum.OP_STATE_CHANGE);
 
 530         notification.setOperationalState(PkgChangeNotification.OperationalStateEnum.ENABLED);
 
 531         notification.setLinks(buildPkgmLinks());
 
 535     private PkgmLinks buildPkgmLinks() {
 
 536         return buildPkgmLinks("vnf_package_href", "subscription_href");
 
 539     private PkgmLinks buildPkgmLinks(final String vnfPkgHref, final String subscriptionHref) {
 
 540         return new PkgmLinks().vnfPackage(new NOTIFICATIONLINKSERIALIZER().href(vnfPkgHref))
 
 541                 .subscription(new NOTIFICATIONLINKSERIALIZER().href(subscriptionHref));
 
 544     private PkgmSubscriptionRequest buildPkgmSubscriptionRequest(
 
 545             final SubscriptionsAuthentication.AuthTypeEnum authTypeEnum) {
 
 546         final PkgmSubscriptionRequest subscriptionRequest = new PkgmSubscriptionRequest();
 
 547         subscriptionRequest.setCallbackUri(CALLBACK_URI.toString());
 
 548         subscriptionRequest.setAuthentication(buildSubscriptionsAuthentication(authTypeEnum));
 
 549         return subscriptionRequest;
 
 552     // TODO update for auth types other than basicAuth
 
 553     private SubscriptionsAuthentication buildSubscriptionsAuthentication(
 
 554             final SubscriptionsAuthentication.AuthTypeEnum authTypeEnum) {
 
 555         final SubscriptionsAuthentication subscriptionsAuthentication = new SubscriptionsAuthentication();
 
 556         final List<SubscriptionsAuthentication.AuthTypeEnum> authTypes = new ArrayList<>();
 
 557         authTypes.add(authTypeEnum);
 
 558         subscriptionsAuthentication.setAuthType(authTypes);
 
 559         if (authTypeEnum == SubscriptionsAuthentication.AuthTypeEnum.TLS_CERT) {
 
 560             // TODO: remove basic params and code for TLS
 
 561             final SubscriptionsAuthenticationParamsBasic basicParams =
 
 562                     new SubscriptionsAuthenticationParamsBasic().userName(USERNAME).password(PASSWORD);
 
 563             subscriptionsAuthentication.setParamsBasic(basicParams);
 
 564         } else if (authTypeEnum == SubscriptionsAuthentication.AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS) {
 
 565             final SubscriptionsAuthenticationParamsOauth2ClientCredentials oathParams =
 
 566                     new SubscriptionsAuthenticationParamsOauth2ClientCredentials().clientId(USERNAME)
 
 567                             .clientPassword(PASSWORD).tokenEndpoint(TOKEN_ENDPOINT);
 
 568             subscriptionsAuthentication.setParamsOauth2ClientCredentials(oathParams);
 
 570             final SubscriptionsAuthenticationParamsBasic basicParams =
 
 571                     new SubscriptionsAuthenticationParamsBasic().userName(USERNAME).password(PASSWORD);
 
 572             subscriptionsAuthentication.setParamsBasic(basicParams);
 
 575         return subscriptionsAuthentication;
 
 578     private <T> ResponseEntity<ProblemDetails> sendHttpPost(final T notification) {
 
 579         final String testURL = LOCALHOST_URL + port + NOTIFICATION_BASE_URL;
 
 580         final HttpEntity<?> request = new HttpEntity<>(notification, basicHttpHeadersProvider.getHttpHeaders());
 
 581         return testRestTemplate.withBasicAuth("test", "test").exchange(testURL, HttpMethod.POST, request,
 
 582                 ProblemDetails.class);
 
 585     private ResponseEntity<Void> sendHttpGet(final String url) {
 
 586         final String testURL = LOCALHOST_URL + port + url;
 
 587         final HttpEntity<?> request = new HttpEntity<>(basicHttpHeadersProvider.getHttpHeaders());
 
 588         return testRestTemplate.withBasicAuth("test", "test").exchange(testURL, HttpMethod.GET, request, Void.class);