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.etsi.sol003.adapter.packagemanagement.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.etsi.sol003.adapter.etsicatalog.notification.model.NOTIFICATIONLINKSERIALIZER;
44 import org.onap.so.adapters.etsi.sol003.adapter.etsicatalog.notification.model.PkgChangeNotification;
45 import org.onap.so.adapters.etsi.sol003.adapter.etsicatalog.notification.model.PkgOnboardingNotification;
46 import org.onap.so.adapters.etsi.sol003.adapter.etsicatalog.notification.model.PkgmLinks;
47 import org.onap.so.adapters.etsi.sol003.adapter.packagemanagement.JSON;
48 import org.onap.so.adapters.etsi.sol003.adapter.packagemanagement.PackageManagementConstants;
49 import org.onap.so.adapters.etsi.sol003.adapter.packagemanagement.extclients.etsicatalog.model.ProblemDetails;
50 import org.onap.so.adapters.etsi.sol003.adapter.packagemanagement.extclients.vnfm.notification.model.VnfPackageChangeNotification;
51 import org.onap.so.adapters.etsi.sol003.adapter.packagemanagement.extclients.vnfm.notification.model.VnfPackageOnboardingNotification;
52 import org.onap.so.adapters.etsi.sol003.adapter.packagemanagement.model.PkgmSubscriptionRequest;
53 import org.onap.so.adapters.etsi.sol003.adapter.packagemanagement.model.SubscriptionsAuthentication;
54 import org.onap.so.adapters.etsi.sol003.adapter.packagemanagement.model.SubscriptionsAuthenticationParamsBasic;
55 import org.onap.so.adapters.etsi.sol003.adapter.packagemanagement.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);