5a330e4ffeea0bb499c34abe02c9890436d669ea
[so.git] /
1 /*-
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
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so.adapters.vnfmadapter.rest;
22
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertTrue;
25 import static org.onap.so.adapters.vnfmadapter.Constants.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.*;
29 import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
30 import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
31 import java.net.URI;
32 import java.util.ArrayList;
33 import java.util.List;
34 import java.util.UUID;
35 import org.junit.After;
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 import org.onap.so.adapters.vnfmadapter.Constants;
40 import org.onap.so.adapters.vnfmadapter.VnfmAdapterApplication;
41 import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.model.ProblemDetails;
42 import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.notification.model.NOTIFICATIONLINKSERIALIZER;
43 import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.notification.model.PkgChangeNotification;
44 import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.notification.model.PkgOnboardingNotification;
45 import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.notification.model.PkgmLinks;
46 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.PkgmSubscriptionRequest;
47 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsAuthentication;
48 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsAuthenticationParamsBasic;
49 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsAuthenticationParamsOauth2ClientCredentials;
50 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.notification.model.VnfPackageChangeNotification;
51 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.notification.model.VnfPackageOnboardingNotification;
52 import org.onap.so.configuration.rest.BasicHttpHeadersProvider;
53 import org.springframework.beans.factory.annotation.Autowired;
54 import org.springframework.beans.factory.annotation.Qualifier;
55 import org.springframework.boot.test.context.SpringBootTest;
56 import org.springframework.boot.test.web.client.TestRestTemplate;
57 import org.springframework.boot.web.server.LocalServerPort;
58 import org.springframework.cache.Cache;
59 import org.springframework.cache.CacheManager;
60 import org.springframework.http.*;
61 import org.springframework.test.annotation.DirtiesContext;
62 import org.springframework.test.context.ActiveProfiles;
63 import org.springframework.test.context.junit4.SpringRunner;
64 import org.springframework.test.web.client.MockRestServiceServer;
65 import org.springframework.web.client.RestTemplate;
66 import org.threeten.bp.LocalDateTime;
67 import org.threeten.bp.OffsetDateTime;
68 import org.threeten.bp.ZoneOffset;
69 import com.google.gson.Gson;
70 import com.google.gson.GsonBuilder;
71
72 /**
73  * @author Andrew Lamb (andrew.a.lamb@est.tech)
74  *
75  */
76 @RunWith(SpringRunner.class)
77 @SpringBootTest(classes = VnfmAdapterApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
78 @ActiveProfiles("test")
79 @DirtiesContext(classMode = BEFORE_CLASS)
80 public class EtsiSubscriptionNotificationControllerTest {
81
82     @LocalServerPort
83     private int port;
84
85     private static final URI CALLBACK_URI = URI.create("http://test_callback_uri/notification");
86     private static final String TOKEN_ENDPOINT = "http://test_token_endpoint_uri/";
87     private static final String TOKEN = "dXNlcm5hbWU6cGFzc3dvcmQ=......";
88     private static final String JSON_TOKEN = "{\"access_token\":\"" + TOKEN + "\"}";
89     private static final String LOCALHOST_URL = "http://localhost:";
90     private static final String NOTIFICATION_BASE_URL =
91             ETSI_SUBSCRIPTION_NOTIFICATION_CONTROLLER_BASE_URL + "/notification";
92     private static final String USERNAME = "username";
93     private static final String PASSWORD = "password";
94     private static final String EXPECTED_BASIC_AUTHORIZATION = "Basic dXNlcm5hbWU6cGFzc3dvcmQ=";
95     private static final String EXPECTED_OAUTH_AUTHORIZATION = "Bearer " + TOKEN;
96     private static final String NOTIFICATION_ID = "NOTIFICATION_ID";
97     private static final String SUBSCRIPTION_ID = "SUBSCRIPTION_ID";
98     private static final OffsetDateTime TIMESTAMP =
99             OffsetDateTime.of(LocalDateTime.of(2020, 1, 1, 1, 1, 1, 1), ZoneOffset.ofHours(1));
100     private static final String VNFPKG_ID = UUID.randomUUID().toString();
101     private static final String VNFD_ID = UUID.randomUUID().toString();
102     private static final String EXPECTED_VNF_PACKAGE_HREF =
103             "https://so-vnfm-adapter.onap:30406/so/vnfm-adapter/v1/vnfpkgm/v1/vnf_packages/" + VNFPKG_ID;
104     private static final String EXPECTED_SUBSCRIPTION_HREF =
105             "https://so-vnfm-adapter.onap:30406/so/vnfm-adapter/v1/vnfpkgm/v1/subscriptions/" + SUBSCRIPTION_ID;
106
107     private BasicHttpHeadersProvider basicHttpHeadersProvider;
108     private final Gson gson = new GsonBuilder().create();;
109
110     @Autowired
111     @Qualifier(CONFIGURABLE_REST_TEMPLATE)
112     private RestTemplate restTemplate;
113     private MockRestServiceServer mockRestServer;
114
115     @Autowired
116     private TestRestTemplate testRestTemplate;
117
118     @Autowired
119     private CacheManager cacheServiceProvider;
120     private Cache cache;
121
122     @Before
123     public void setUp() {
124         mockRestServer = MockRestServiceServer.bindTo(restTemplate).build();
125         basicHttpHeadersProvider = new BasicHttpHeadersProvider();
126         cache = cacheServiceProvider.getCache(Constants.PACKAGE_MANAGEMENT_SUBSCRIPTION_CACHE);
127         cache.clear();
128     }
129
130     @After
131     public void tearDown() {
132         cache.clear();
133     }
134
135     @Test
136     public void testSubscriptionNotificationEndPoint_ReturnsNoContent() {
137         final ResponseEntity<?> response = sendHttpGet(NOTIFICATION_BASE_URL);
138         assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
139     }
140
141     @Test
142     public void testOnboardingNotificationSentOnToVnfmCallbackUri_SubscriptionRequestInCache_Success() {
143         final PkgmSubscriptionRequest subscriptionRequest =
144                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
145         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
146         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
147         final String notificationString = gson.toJson(notification);
148
149         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
150                 .andExpect(jsonPath("$.id").value(NOTIFICATION_ID))
151                 .andExpect(jsonPath("$.notificationType")
152                         .value(VnfPackageOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION
153                                 .toString()))
154                 .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID))
155                 .andExpect(jsonPath("$.timeStamp").value(TIMESTAMP.toString()))
156                 .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID.toString()))
157                 .andExpect(jsonPath("$.vnfdId").value(VNFD_ID.toString()))
158                 .andExpect(jsonPath("$._links")
159                         .value(buildPkgmLinks(EXPECTED_VNF_PACKAGE_HREF, EXPECTED_SUBSCRIPTION_HREF)))
160                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess());
161
162         final ResponseEntity<?> response = sendHttpPost(notificationString);
163
164         assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
165     }
166
167     @Test
168     public void testOnboardingNotificationNotSentOnToVnfmCallbackUri_SubscriptionRequestNotInCache_Fail() {
169         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
170         final String notificationString = gson.toJson(notification);
171         final ResponseEntity<?> response = sendHttpPost(notificationString);
172
173         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
174         assertTrue(response.getBody() instanceof ProblemDetails);
175
176         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
177         final String errorMessage = "No subscription found with subscriptionId " + SUBSCRIPTION_ID
178                 + ". Unable to forward notification to subscriber.";
179
180         assertEquals(errorMessage, problemDetails.getDetail());
181     }
182
183     @Test
184     public void testOnboardingNotificationSentOnToVnfmCallbackUri_BadRequestResponseFromCallbackUri_Fail() {
185         final PkgmSubscriptionRequest subscriptionRequest =
186                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
187         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
188         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
189         final String notificationString = gson.toJson(notification);
190
191         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
192                 .andRespond(withStatus(HttpStatus.BAD_REQUEST));
193
194         final ResponseEntity<?> response = sendHttpPost(notificationString);
195
196         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
197         assertTrue(response.getBody() instanceof ProblemDetails);
198
199         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
200         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
201                 + HttpStatus.BAD_REQUEST + ".\n" + "No result found for given url: " + CALLBACK_URI;
202
203         assertEquals(errorMessage, problemDetails.getDetail());
204     }
205
206     @Test
207     public void testOnboardingNotificationSentOnToVnfmCallbackUri_301MovedPermanentlyResponseFromCallbackUri_Fail() {
208         final PkgmSubscriptionRequest subscriptionRequest =
209                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
210         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
211         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
212         final String notificationString = gson.toJson(notification);
213
214         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
215                 .andRespond(withStatus(HttpStatus.MOVED_PERMANENTLY));
216
217         final ResponseEntity<?> response = sendHttpPost(notificationString);
218
219         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
220         assertTrue(response.getBody() instanceof ProblemDetails);
221
222         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
223         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed.";
224
225         assertEquals(errorMessage, problemDetails.getDetail());
226     }
227
228     @Test
229     public void testOnboardingNotificationSentOnToVnfmCallbackUri_NotFoundResponseFromCallbackUri_Fail() {
230         final PkgmSubscriptionRequest subscriptionRequest =
231                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
232         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
233         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
234         final String notificationString = gson.toJson(notification);
235
236         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
237                 .andRespond(withStatus(HttpStatus.NOT_FOUND));
238
239         final ResponseEntity<?> response = sendHttpPost(notificationString);
240
241         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
242         assertTrue(response.getBody() instanceof ProblemDetails);
243
244         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
245         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
246                 + HttpStatus.NOT_FOUND + ".\n" + "No result found for given url: " + CALLBACK_URI;
247
248         assertEquals(errorMessage, problemDetails.getDetail());
249     }
250
251     @Test
252     public void testOnboardingNotificationSentOnToVnfmCallbackUri_InternalServerErrorResponseFromCallbackUri_Fail() {
253         final PkgmSubscriptionRequest subscriptionRequest =
254                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
255         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
256         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
257         final String notificationString = gson.toJson(notification);
258
259         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
260                 .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
261
262         final ResponseEntity<?> response = sendHttpPost(notificationString);
263
264         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
265         assertTrue(response.getBody() instanceof ProblemDetails);
266
267         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
268         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
269                 + HttpStatus.INTERNAL_SERVER_ERROR.value() + ".\n" + "Unable to invoke HTTP POST using URL: "
270                 + CALLBACK_URI;
271
272         assertEquals(errorMessage, problemDetails.getDetail());
273     }
274
275     @Test
276     public void testChangeNotificationSentOnToVnfmCallbackUri_SubscriptionRequestInCache_Success() {
277         final PkgmSubscriptionRequest subscriptionRequest =
278                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
279         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
280         final PkgChangeNotification notification = buildPkgChangeNotification();
281         final String notificationString = gson.toJson(notification);
282
283         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
284                 .andExpect(jsonPath("$.id").value(NOTIFICATION_ID))
285                 .andExpect(jsonPath("$.notificationType").value(
286                         VnfPackageChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION.getValue()))
287                 .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID))
288                 .andExpect(jsonPath("$.timeStamp").value(TIMESTAMP.toString()))
289                 .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID.toString()))
290                 .andExpect(jsonPath("$.vnfdId").value(VNFD_ID.toString()))
291                 .andExpect(
292                         jsonPath("$.changeType").value(PkgChangeNotification.ChangeTypeEnum.OP_STATE_CHANGE.toString()))
293                 .andExpect(jsonPath("$.operationalState")
294                         .value(PkgChangeNotification.OperationalStateEnum.ENABLED.toString()))
295                 .andExpect(jsonPath("$._links")
296                         .value(buildPkgmLinks(EXPECTED_VNF_PACKAGE_HREF, EXPECTED_SUBSCRIPTION_HREF)))
297                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess());
298
299         final ResponseEntity<?> response = sendHttpPost(notificationString);
300
301         assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
302     }
303
304     @Test
305     public void testChangeNotificationNotSentOnToVnfmCallbackUri_SubscriptionRequestNotInCache_Fail() {
306         final PkgChangeNotification notification = buildPkgChangeNotification();
307         final String notificationString = gson.toJson(notification);
308         final ResponseEntity<?> response = sendHttpPost(notificationString);
309
310         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
311         assertTrue(response.getBody() instanceof ProblemDetails);
312
313         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
314         final String errorMessage = "No subscription found with subscriptionId " + SUBSCRIPTION_ID
315                 + ". Unable to forward notification to subscriber.";
316
317         assertEquals(errorMessage, problemDetails.getDetail());
318     }
319
320     @Test
321     public void testChangeNotificationSentOnToVnfmCallbackUri_BadRequestResponseFromCallbackUri_Fail() {
322         final PkgmSubscriptionRequest subscriptionRequest =
323                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
324         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
325         final PkgChangeNotification notification = buildPkgChangeNotification();
326         final String notificationString = gson.toJson(notification);
327
328         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
329                 .andRespond(withStatus(HttpStatus.BAD_REQUEST));
330
331         final ResponseEntity<?> response = sendHttpPost(notificationString);
332
333         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
334         assertTrue(response.getBody() instanceof ProblemDetails);
335
336         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
337         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
338                 + HttpStatus.BAD_REQUEST + ".\n" + "No result found for given url: " + CALLBACK_URI;
339
340         assertEquals(errorMessage, problemDetails.getDetail());
341     }
342
343     @Test
344     public void testChangeNotificationSentOnToVnfmCallbackUri_NotFoundResponseFromCallbackUri_Fail() {
345         final PkgmSubscriptionRequest subscriptionRequest =
346                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
347         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
348         final PkgChangeNotification notification = buildPkgChangeNotification();
349         final String notificationString = gson.toJson(notification);
350
351         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
352                 .andRespond(withStatus(HttpStatus.NOT_FOUND));
353
354         final ResponseEntity<?> response = sendHttpPost(notificationString);
355
356         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
357         assertTrue(response.getBody() instanceof ProblemDetails);
358
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;
362
363         assertEquals(errorMessage, problemDetails.getDetail());
364     }
365
366     @Test
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();
372         final String notificationString = gson.toJson(notification);
373
374         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
375                 .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
376
377         final ResponseEntity<?> response = sendHttpPost(notificationString);
378
379         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
380         assertTrue(response.getBody() instanceof ProblemDetails);
381
382         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
383         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
384                 + HttpStatus.INTERNAL_SERVER_ERROR.value() + ".\n" + "Unable to invoke HTTP POST using URL: "
385                 + CALLBACK_URI;
386
387         assertEquals(errorMessage, problemDetails.getDetail());
388     }
389
390     @Test
391     public void testNotificationSentOnToVnfm_BasicAuthUserPasswordAuthorized_Success() {
392         final PkgmSubscriptionRequest subscriptionRequest =
393                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
394         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
395         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
396         final String notificationString = gson.toJson(notification);
397
398         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
399                 .andExpect(jsonPath("$.id").value(NOTIFICATION_ID))
400                 .andExpect(jsonPath("$.notificationType")
401                         .value(VnfPackageOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION
402                                 .toString()))
403                 .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID))
404                 .andExpect(jsonPath("$.timeStamp").value(TIMESTAMP.toString()))
405                 .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID.toString()))
406                 .andExpect(jsonPath("$.vnfdId").value(VNFD_ID.toString()))
407                 .andExpect(jsonPath("$._links")
408                         .value(buildPkgmLinks(EXPECTED_VNF_PACKAGE_HREF, EXPECTED_SUBSCRIPTION_HREF)))
409                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess());
410
411         final ResponseEntity<?> response = sendHttpPost(notificationString);
412
413         assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
414     }
415
416     @Test
417     public void testNotificationSentOnToVnfm_BasicAuthUserPasswordNotAuthorized_Fail() {
418         final PkgmSubscriptionRequest subscriptionRequest =
419                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
420         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
421         final PkgChangeNotification notification = buildPkgChangeNotification();
422         final String notificationString = gson.toJson(notification);
423
424         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
425                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION))
426                 .andRespond(withStatus(HttpStatus.UNAUTHORIZED));
427
428         final ResponseEntity<?> response = sendHttpPost(notificationString);
429
430         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
431         assertTrue(response.getBody() instanceof ProblemDetails);
432
433         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
434         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
435                 + HttpStatus.UNAUTHORIZED.value() + ".\n" + "Unable to invoke HTTP POST using URL: " + CALLBACK_URI;
436
437         assertEquals(errorMessage, problemDetails.getDetail());
438     }
439
440     @Test
441     public void testNotificationSentOnToVnfm_OAuthAuthorized_Success() {
442         final PkgmSubscriptionRequest subscriptionRequest =
443                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS);
444         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
445         final PkgChangeNotification notification = buildPkgChangeNotification();
446         final String notificationString = gson.toJson(notification);
447
448         mockRestServer.expect(requestTo(TOKEN_ENDPOINT)).andExpect(method(HttpMethod.POST))
449                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION))
450                 .andRespond(withSuccess(JSON_TOKEN, MediaType.APPLICATION_JSON));
451
452         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
453                 .andExpect(header("Authorization", EXPECTED_OAUTH_AUTHORIZATION))
454                 .andExpect(jsonPath("$.id").value(NOTIFICATION_ID))
455                 .andExpect(jsonPath("$.notificationType").value(
456                         VnfPackageChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION.toString()))
457                 .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID))
458                 .andExpect(jsonPath("$.timeStamp").value(TIMESTAMP.toString()))
459                 .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID.toString()))
460                 .andExpect(jsonPath("$.vnfdId").value(VNFD_ID.toString()))
461                 .andExpect(
462                         jsonPath("$.changeType").value(PkgChangeNotification.ChangeTypeEnum.OP_STATE_CHANGE.toString()))
463                 .andExpect(jsonPath("$.operationalState")
464                         .value(PkgChangeNotification.OperationalStateEnum.ENABLED.toString()))
465                 .andExpect(jsonPath("$._links")
466                         .value(buildPkgmLinks(EXPECTED_VNF_PACKAGE_HREF, EXPECTED_SUBSCRIPTION_HREF)))
467                 .andRespond(withSuccess());
468
469         final ResponseEntity<?> response = sendHttpPost(notificationString);
470
471         assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
472     }
473
474     @Test
475     public void testNotificationSentOnToVnfm_OAuthTokenNotReceived_Fail() {
476         final PkgmSubscriptionRequest subscriptionRequest =
477                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS);
478         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
479         final PkgChangeNotification notification = buildPkgChangeNotification();
480         final String notificationString = gson.toJson(notification);
481
482         mockRestServer.expect(requestTo(TOKEN_ENDPOINT)).andExpect(method(HttpMethod.POST))
483                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess());
484
485         final ResponseEntity<?> response = sendHttpPost(notificationString);
486
487         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
488         assertTrue(response.getBody() instanceof ProblemDetails);
489
490         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
491         final String errorMessage = "An error occurred.  Unable to retrieve OAuth Token from VNFM for notification.";
492
493         assertEquals(errorMessage, problemDetails.getDetail());
494     }
495
496     @Test
497     public void testNotificationSentOnToVnfm_TLSCertNotYetSupported_Fail() {
498         final PkgmSubscriptionRequest subscriptionRequest =
499                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.TLS_CERT);
500         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
501         final PkgChangeNotification notification = buildPkgChangeNotification();
502         final String notificationString = gson.toJson(notification);
503
504         final ResponseEntity<?> response = sendHttpPost(notificationString);
505
506         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
507         assertTrue(response.getBody() instanceof ProblemDetails);
508
509         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
510         final String errorMessage = "An error occurred.  Authentication type "
511                 + subscriptionRequest.getAuthentication().getAuthType().toString() + " not currently supported.";
512
513         assertEquals(errorMessage, problemDetails.getDetail());
514     }
515
516     private PkgOnboardingNotification buildPkgOnboardingNotification() {
517         final PkgOnboardingNotification notification = new PkgOnboardingNotification();
518         notification.setId(NOTIFICATION_ID);
519         notification
520                 .setNotificationType(PkgOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION);
521         notification.setSubscriptionId(SUBSCRIPTION_ID);
522         notification.setTimeStamp(TIMESTAMP);
523         notification.setVnfPkgId(VNFPKG_ID);
524         notification.setVnfdId(VNFD_ID);
525         notification.setLinks(buildPkgmLinks());
526         return notification;
527     }
528
529     private PkgChangeNotification buildPkgChangeNotification() {
530         final PkgChangeNotification notification = new PkgChangeNotification();
531         notification.setId(NOTIFICATION_ID);
532         notification.setNotificationType(PkgChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION);
533         notification.setSubscriptionId(SUBSCRIPTION_ID);
534         notification.setTimeStamp(TIMESTAMP);
535         notification.setVnfPkgId(VNFPKG_ID);
536         notification.setVnfdId(VNFD_ID);
537         notification.setChangeType(PkgChangeNotification.ChangeTypeEnum.OP_STATE_CHANGE);
538         notification.setOperationalState(PkgChangeNotification.OperationalStateEnum.ENABLED);
539         notification.setLinks(buildPkgmLinks());
540         return notification;
541     }
542
543     private PkgmLinks buildPkgmLinks() {
544         return buildPkgmLinks("vnf_package_href", "subscription_href");
545     }
546
547     private PkgmLinks buildPkgmLinks(final String vnfPkgHref, final String subscriptionHref) {
548         return new PkgmLinks().vnfPackage(new NOTIFICATIONLINKSERIALIZER().href(vnfPkgHref))
549                 .subscription(new NOTIFICATIONLINKSERIALIZER().href(subscriptionHref));
550     }
551
552     private PkgmSubscriptionRequest buildPkgmSubscriptionRequest(
553             final SubscriptionsAuthentication.AuthTypeEnum authTypeEnum) {
554         final PkgmSubscriptionRequest subscriptionRequest = new PkgmSubscriptionRequest();
555         subscriptionRequest.setCallbackUri(CALLBACK_URI.toString());
556         subscriptionRequest.setAuthentication(buildSubscriptionsAuthentication(authTypeEnum));
557         return subscriptionRequest;
558     }
559
560     // TODO update for auth types other than basicAuth
561     private SubscriptionsAuthentication buildSubscriptionsAuthentication(
562             final SubscriptionsAuthentication.AuthTypeEnum authTypeEnum) {
563         final SubscriptionsAuthentication subscriptionsAuthentication = new SubscriptionsAuthentication();
564         final List<SubscriptionsAuthentication.AuthTypeEnum> authTypes = new ArrayList<>();
565         authTypes.add(authTypeEnum);
566         subscriptionsAuthentication.setAuthType(authTypes);
567         if (authTypeEnum == SubscriptionsAuthentication.AuthTypeEnum.TLS_CERT) {
568             // TODO: remove basic params and code for TLS
569             final SubscriptionsAuthenticationParamsBasic basicParams =
570                     new SubscriptionsAuthenticationParamsBasic().userName(USERNAME).password(PASSWORD);
571             subscriptionsAuthentication.setParamsBasic(basicParams);
572         } else if (authTypeEnum == SubscriptionsAuthentication.AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS) {
573             final SubscriptionsAuthenticationParamsOauth2ClientCredentials oathParams =
574                     new SubscriptionsAuthenticationParamsOauth2ClientCredentials().clientId(USERNAME)
575                             .clientPassword(PASSWORD).tokenEndpoint(TOKEN_ENDPOINT);
576             subscriptionsAuthentication.setParamsOauth2ClientCredentials(oathParams);
577         } else {
578             final SubscriptionsAuthenticationParamsBasic basicParams =
579                     new SubscriptionsAuthenticationParamsBasic().userName(USERNAME).password(PASSWORD);
580             subscriptionsAuthentication.setParamsBasic(basicParams);
581         }
582
583         return subscriptionsAuthentication;
584     }
585
586     private <T> ResponseEntity<ProblemDetails> sendHttpPost(final T notification) {
587         final String testURL = LOCALHOST_URL + port + NOTIFICATION_BASE_URL;
588         final HttpEntity<?> request = new HttpEntity<>(notification, basicHttpHeadersProvider.getHttpHeaders());
589         return testRestTemplate.withBasicAuth("test", "test").exchange(testURL, HttpMethod.POST, request,
590                 ProblemDetails.class);
591     }
592
593     private ResponseEntity<Void> sendHttpGet(final String url) {
594         final String testURL = LOCALHOST_URL + port + url;
595         final HttpEntity<?> request = new HttpEntity<>(basicHttpHeadersProvider.getHttpHeaders());
596         return testRestTemplate.withBasicAuth("test", "test").exchange(testURL, HttpMethod.GET, request, Void.class);
597     }
598
599 }