322251e753500753ce0a3bb27bb34ee91508befd
[so.git] / adapters / mso-vnfm-adapter / mso-vnfm-etsi-adapter / src / test / java / org / onap / so / adapters / vnfmadapter / rest / EtsiSubscriptionNotificationControllerTest.java
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
103     private BasicHttpHeadersProvider basicHttpHeadersProvider;
104     private final Gson gson = new GsonBuilder().create();;
105
106     @Autowired
107     @Qualifier(CONFIGURABLE_REST_TEMPLATE)
108     private RestTemplate restTemplate;
109     private MockRestServiceServer mockRestServer;
110
111     @Autowired
112     private TestRestTemplate testRestTemplate;
113
114     @Autowired
115     private CacheManager cacheServiceProvider;
116     private Cache cache;
117
118     @Before
119     public void setUp() {
120         mockRestServer = MockRestServiceServer.bindTo(restTemplate).build();
121         basicHttpHeadersProvider = new BasicHttpHeadersProvider();
122         cache = cacheServiceProvider.getCache(Constants.PACKAGE_MANAGEMENT_SUBSCRIPTION_CACHE);
123         cache.clear();
124     }
125
126     @After
127     public void tearDown() {
128         cache.clear();
129     }
130
131     @Test
132     public void testSubscriptionNotificationEndPoint_ReturnsNoContent() {
133         final ResponseEntity<?> response = sendHttpGet(NOTIFICATION_BASE_URL);
134         assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
135     }
136
137     @Test
138     public void testOnboardingNotificationSentOnToVnfmCallbackUri_SubscriptionRequestInCache_Success() {
139         final PkgmSubscriptionRequest subscriptionRequest =
140                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
141         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
142         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
143         final String notificationString = gson.toJson(notification);
144
145         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
146                 .andExpect(jsonPath("$.id").value(NOTIFICATION_ID))
147                 .andExpect(jsonPath("$.notificationType")
148                         .value(VnfPackageOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION
149                                 .toString()))
150                 .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID))
151                 .andExpect(jsonPath("$.timeStamp").value(TIMESTAMP.toString()))
152                 .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID.toString()))
153                 .andExpect(jsonPath("$.vnfdId").value(VNFD_ID.toString()))
154                 .andExpect(jsonPath("$._links").value(buildPkgmLinks()))
155                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess());
156
157         final ResponseEntity<?> response = sendHttpPost(notificationString);
158
159         assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
160     }
161
162     @Test
163     public void testOnboardingNotificationNotSentOnToVnfmCallbackUri_SubscriptionRequestNotInCache_Fail() {
164         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
165         final String notificationString = gson.toJson(notification);
166         final ResponseEntity<?> response = sendHttpPost(notificationString);
167
168         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
169         assertTrue(response.getBody() instanceof ProblemDetails);
170
171         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
172         final String errorMessage = "No subscription found with subscriptionId " + SUBSCRIPTION_ID
173                 + ". Unable to forward notification to subscriber.";
174
175         assertEquals(errorMessage, problemDetails.getDetail());
176     }
177
178     @Test
179     public void testOnboardingNotificationSentOnToVnfmCallbackUri_BadRequestResponseFromCallbackUri_Fail() {
180         final PkgmSubscriptionRequest subscriptionRequest =
181                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
182         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
183         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
184         final String notificationString = gson.toJson(notification);
185
186         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
187                 .andRespond(withStatus(HttpStatus.BAD_REQUEST));
188
189         final ResponseEntity<?> response = sendHttpPost(notificationString);
190
191         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
192         assertTrue(response.getBody() instanceof ProblemDetails);
193
194         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
195         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
196                 + HttpStatus.BAD_REQUEST + ".\n" + "No result found for given url: " + CALLBACK_URI;
197
198         assertEquals(errorMessage, problemDetails.getDetail());
199     }
200
201     @Test
202     public void testOnboardingNotificationSentOnToVnfmCallbackUri_301MovedPermanentlyResponseFromCallbackUri_Fail() {
203         final PkgmSubscriptionRequest subscriptionRequest =
204                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
205         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
206         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
207         final String notificationString = gson.toJson(notification);
208
209         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
210                 .andRespond(withStatus(HttpStatus.MOVED_PERMANENTLY));
211
212         final ResponseEntity<?> response = sendHttpPost(notificationString);
213
214         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
215         assertTrue(response.getBody() instanceof ProblemDetails);
216
217         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
218         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed.";
219
220         assertEquals(errorMessage, problemDetails.getDetail());
221     }
222
223     @Test
224     public void testOnboardingNotificationSentOnToVnfmCallbackUri_NotFoundResponseFromCallbackUri_Fail() {
225         final PkgmSubscriptionRequest subscriptionRequest =
226                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
227         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
228         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
229         final String notificationString = gson.toJson(notification);
230
231         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
232                 .andRespond(withStatus(HttpStatus.NOT_FOUND));
233
234         final ResponseEntity<?> response = sendHttpPost(notificationString);
235
236         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
237         assertTrue(response.getBody() instanceof ProblemDetails);
238
239         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
240         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
241                 + HttpStatus.NOT_FOUND + ".\n" + "No result found for given url: " + CALLBACK_URI;
242
243         assertEquals(errorMessage, problemDetails.getDetail());
244     }
245
246     @Test
247     public void testOnboardingNotificationSentOnToVnfmCallbackUri_InternalServerErrorResponseFromCallbackUri_Fail() {
248         final PkgmSubscriptionRequest subscriptionRequest =
249                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
250         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
251         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
252         final String notificationString = gson.toJson(notification);
253
254         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
255                 .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
256
257         final ResponseEntity<?> response = sendHttpPost(notificationString);
258
259         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
260         assertTrue(response.getBody() instanceof ProblemDetails);
261
262         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
263         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
264                 + HttpStatus.INTERNAL_SERVER_ERROR.value() + ".\n" + "Unable to invoke HTTP POST using URL: "
265                 + CALLBACK_URI;
266
267         assertEquals(errorMessage, problemDetails.getDetail());
268     }
269
270     @Test
271     public void testChangeNotificationSentOnToVnfmCallbackUri_SubscriptionRequestInCache_Success() {
272         final PkgmSubscriptionRequest subscriptionRequest =
273                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
274         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
275         final PkgChangeNotification notification = buildPkgChangeNotification();
276         final String notificationString = gson.toJson(notification);
277
278         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
279                 .andExpect(jsonPath("$.id").value(NOTIFICATION_ID))
280                 .andExpect(jsonPath("$.notificationType").value(
281                         VnfPackageChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION.toString()))
282                 .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID))
283                 .andExpect(jsonPath("$.timeStamp").value(TIMESTAMP.toString()))
284                 .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID.toString()))
285                 .andExpect(jsonPath("$.vnfdId").value(VNFD_ID.toString()))
286                 .andExpect(
287                         jsonPath("$.changeType").value(PkgChangeNotification.ChangeTypeEnum.OP_STATE_CHANGE.toString()))
288                 .andExpect(jsonPath("$.operationalState")
289                         .value(PkgChangeNotification.OperationalStateEnum.ENABLED.toString()))
290                 .andExpect(jsonPath("$._links").value(buildPkgmLinks()))
291                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess());
292
293         final ResponseEntity<?> response = sendHttpPost(notificationString);
294
295         assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
296     }
297
298     @Test
299     public void testChangeNotificationNotSentOnToVnfmCallbackUri_SubscriptionRequestNotInCache_Fail() {
300         final PkgChangeNotification notification = buildPkgChangeNotification();
301         final String notificationString = gson.toJson(notification);
302         final ResponseEntity<?> response = sendHttpPost(notificationString);
303
304         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
305         assertTrue(response.getBody() instanceof ProblemDetails);
306
307         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
308         final String errorMessage = "No subscription found with subscriptionId " + SUBSCRIPTION_ID
309                 + ". Unable to forward notification to subscriber.";
310
311         assertEquals(errorMessage, problemDetails.getDetail());
312     }
313
314     @Test
315     public void testChangeNotificationSentOnToVnfmCallbackUri_BadRequestResponseFromCallbackUri_Fail() {
316         final PkgmSubscriptionRequest subscriptionRequest =
317                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
318         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
319         final PkgChangeNotification notification = buildPkgChangeNotification();
320         final String notificationString = gson.toJson(notification);
321
322         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
323                 .andRespond(withStatus(HttpStatus.BAD_REQUEST));
324
325         final ResponseEntity<?> response = sendHttpPost(notificationString);
326
327         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
328         assertTrue(response.getBody() instanceof ProblemDetails);
329
330         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
331         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
332                 + HttpStatus.BAD_REQUEST + ".\n" + "No result found for given url: " + CALLBACK_URI;
333
334         assertEquals(errorMessage, problemDetails.getDetail());
335     }
336
337     @Test
338     public void testChangeNotificationSentOnToVnfmCallbackUri_NotFoundResponseFromCallbackUri_Fail() {
339         final PkgmSubscriptionRequest subscriptionRequest =
340                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
341         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
342         final PkgChangeNotification notification = buildPkgChangeNotification();
343         final String notificationString = gson.toJson(notification);
344
345         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
346                 .andRespond(withStatus(HttpStatus.NOT_FOUND));
347
348         final ResponseEntity<?> response = sendHttpPost(notificationString);
349
350         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
351         assertTrue(response.getBody() instanceof ProblemDetails);
352
353         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
354         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
355                 + HttpStatus.NOT_FOUND + ".\n" + "No result found for given url: " + CALLBACK_URI;
356
357         assertEquals(errorMessage, problemDetails.getDetail());
358     }
359
360     @Test
361     public void testChangeNotificationSentOnToVnfmCallbackUri_InternalServerErrorResponseFromCallbackUri_Fail() {
362         final PkgmSubscriptionRequest subscriptionRequest =
363                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
364         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
365         final PkgChangeNotification notification = buildPkgChangeNotification();
366         final String notificationString = gson.toJson(notification);
367
368         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
369                 .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
370
371         final ResponseEntity<?> response = sendHttpPost(notificationString);
372
373         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
374         assertTrue(response.getBody() instanceof ProblemDetails);
375
376         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
377         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
378                 + HttpStatus.INTERNAL_SERVER_ERROR.value() + ".\n" + "Unable to invoke HTTP POST using URL: "
379                 + CALLBACK_URI;
380
381         assertEquals(errorMessage, problemDetails.getDetail());
382     }
383
384     @Test
385     public void testNotificationSentOnToVnfm_BasicAuthUserPasswordAuthorized_Success() {
386         final PkgmSubscriptionRequest subscriptionRequest =
387                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
388         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
389         final PkgOnboardingNotification notification = buildPkgOnboardingNotification();
390         final String notificationString = gson.toJson(notification);
391
392         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
393                 .andExpect(jsonPath("$.id").value(NOTIFICATION_ID))
394                 .andExpect(jsonPath("$.notificationType")
395                         .value(VnfPackageOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION
396                                 .toString()))
397                 .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID))
398                 .andExpect(jsonPath("$.timeStamp").value(TIMESTAMP.toString()))
399                 .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID.toString()))
400                 .andExpect(jsonPath("$.vnfdId").value(VNFD_ID.toString()))
401                 .andExpect(jsonPath("$._links").value(buildPkgmLinks()))
402                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess());
403
404         final ResponseEntity<?> response = sendHttpPost(notificationString);
405
406         assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
407     }
408
409     @Test
410     public void testNotificationSentOnToVnfm_BasicAuthUserPasswordNotAuthorized_Fail() {
411         final PkgmSubscriptionRequest subscriptionRequest =
412                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC);
413         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
414         final PkgChangeNotification notification = buildPkgChangeNotification();
415         final String notificationString = gson.toJson(notification);
416
417         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
418                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION))
419                 .andRespond(withStatus(HttpStatus.UNAUTHORIZED));
420
421         final ResponseEntity<?> response = sendHttpPost(notificationString);
422
423         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
424         assertTrue(response.getBody() instanceof ProblemDetails);
425
426         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
427         final String errorMessage = "An error occurred.  Sending of notification to VNFM failed with response: "
428                 + HttpStatus.UNAUTHORIZED.value() + ".\n" + "Unable to invoke HTTP POST using URL: " + CALLBACK_URI;
429
430         assertEquals(errorMessage, problemDetails.getDetail());
431     }
432
433     @Test
434     public void testNotificationSentOnToVnfm_OAuthAuthorized_Success() {
435         final PkgmSubscriptionRequest subscriptionRequest =
436                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS);
437         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
438         final PkgChangeNotification notification = buildPkgChangeNotification();
439         final String notificationString = gson.toJson(notification);
440
441         mockRestServer.expect(requestTo(TOKEN_ENDPOINT)).andExpect(method(HttpMethod.POST))
442                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION))
443                 .andRespond(withSuccess(JSON_TOKEN, MediaType.APPLICATION_JSON));
444
445         mockRestServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST))
446                 .andExpect(header("Authorization", EXPECTED_OAUTH_AUTHORIZATION))
447                 .andExpect(jsonPath("$.id").value(NOTIFICATION_ID))
448                 .andExpect(jsonPath("$.notificationType").value(
449                         VnfPackageChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION.toString()))
450                 .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID))
451                 .andExpect(jsonPath("$.timeStamp").value(TIMESTAMP.toString()))
452                 .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID.toString()))
453                 .andExpect(jsonPath("$.vnfdId").value(VNFD_ID.toString()))
454                 .andExpect(
455                         jsonPath("$.changeType").value(PkgChangeNotification.ChangeTypeEnum.OP_STATE_CHANGE.toString()))
456                 .andExpect(jsonPath("$.operationalState")
457                         .value(PkgChangeNotification.OperationalStateEnum.ENABLED.toString()))
458                 .andExpect(jsonPath("$._links").value(buildPkgmLinks())).andRespond(withSuccess());
459
460         final ResponseEntity<?> response = sendHttpPost(notificationString);
461
462         assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
463     }
464
465     @Test
466     public void testNotificationSentOnToVnfm_OAuthTokenNotReceived_Fail() {
467         final PkgmSubscriptionRequest subscriptionRequest =
468                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS);
469         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
470         final PkgChangeNotification notification = buildPkgChangeNotification();
471         final String notificationString = gson.toJson(notification);
472
473         mockRestServer.expect(requestTo(TOKEN_ENDPOINT)).andExpect(method(HttpMethod.POST))
474                 .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess());
475
476         final ResponseEntity<?> response = sendHttpPost(notificationString);
477
478         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
479         assertTrue(response.getBody() instanceof ProblemDetails);
480
481         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
482         final String errorMessage = "An error occurred.  Unable to retrieve OAuth Token from VNFM for notification.";
483
484         assertEquals(errorMessage, problemDetails.getDetail());
485     }
486
487     @Test
488     public void testNotificationSentOnToVnfm_TLSCertNotYetSupported_Fail() {
489         final PkgmSubscriptionRequest subscriptionRequest =
490                 buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.TLS_CERT);
491         cache.put(SUBSCRIPTION_ID, subscriptionRequest);
492         final PkgChangeNotification notification = buildPkgChangeNotification();
493         final String notificationString = gson.toJson(notification);
494
495         final ResponseEntity<?> response = sendHttpPost(notificationString);
496
497         assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
498         assertTrue(response.getBody() instanceof ProblemDetails);
499
500         final ProblemDetails problemDetails = (ProblemDetails) response.getBody();
501         final String errorMessage = "An error occurred.  Authentication type "
502                 + subscriptionRequest.getAuthentication().getAuthType().toString() + " not currently supported.";
503
504         assertEquals(errorMessage, problemDetails.getDetail());
505     }
506
507     private PkgOnboardingNotification buildPkgOnboardingNotification() {
508         final PkgOnboardingNotification notification = new PkgOnboardingNotification();
509         notification.setId(NOTIFICATION_ID);
510         notification
511                 .setNotificationType(PkgOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION);
512         notification.setSubscriptionId(SUBSCRIPTION_ID);
513         notification.setTimeStamp(TIMESTAMP);
514         notification.setVnfPkgId(VNFPKG_ID);
515         notification.setVnfdId(VNFD_ID);
516         notification.setLinks(buildPkgmLinks());
517         return notification;
518     }
519
520     private PkgChangeNotification buildPkgChangeNotification() {
521         final PkgChangeNotification notification = new PkgChangeNotification();
522         notification.setId(NOTIFICATION_ID);
523         notification.setNotificationType(PkgChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION);
524         notification.setSubscriptionId(SUBSCRIPTION_ID);
525         notification.setTimeStamp(TIMESTAMP);
526         notification.setVnfPkgId(VNFPKG_ID);
527         notification.setVnfdId(VNFD_ID);
528         notification.setChangeType(PkgChangeNotification.ChangeTypeEnum.OP_STATE_CHANGE);
529         notification.setOperationalState(PkgChangeNotification.OperationalStateEnum.ENABLED);
530         notification.setLinks(buildPkgmLinks());
531         return notification;
532     }
533
534     private PkgmLinks buildPkgmLinks() {
535         final PkgmLinks pkgmLinks = new PkgmLinks();
536
537         final NOTIFICATIONLINKSERIALIZER subscriptionLinkSerializer = new NOTIFICATIONLINKSERIALIZER();
538         subscriptionLinkSerializer.setHref("subscription_href");
539         pkgmLinks.setSubscription(subscriptionLinkSerializer);
540
541         final NOTIFICATIONLINKSERIALIZER vnfPackageLinkSerializer = new NOTIFICATIONLINKSERIALIZER();
542         vnfPackageLinkSerializer.setHref("vnf_package_href");
543         pkgmLinks.setVnfPackage(vnfPackageLinkSerializer);
544
545         return pkgmLinks;
546     }
547
548     private PkgmSubscriptionRequest buildPkgmSubscriptionRequest(
549             final SubscriptionsAuthentication.AuthTypeEnum authTypeEnum) {
550         final PkgmSubscriptionRequest subscriptionRequest = new PkgmSubscriptionRequest();
551         subscriptionRequest.setCallbackUri(CALLBACK_URI.toString());
552         subscriptionRequest.setAuthentication(buildSubscriptionsAuthentication(authTypeEnum));
553         return subscriptionRequest;
554     }
555
556     // TODO update for auth types other than basicAuth
557     private SubscriptionsAuthentication buildSubscriptionsAuthentication(
558             final SubscriptionsAuthentication.AuthTypeEnum authTypeEnum) {
559         final SubscriptionsAuthentication subscriptionsAuthentication = new SubscriptionsAuthentication();
560         final List<SubscriptionsAuthentication.AuthTypeEnum> authTypes = new ArrayList<>();
561         authTypes.add(authTypeEnum);
562         subscriptionsAuthentication.setAuthType(authTypes);
563         if (authTypeEnum == SubscriptionsAuthentication.AuthTypeEnum.TLS_CERT) {
564             // TODO: remove basic params and code for TLS
565             final SubscriptionsAuthenticationParamsBasic basicParams =
566                     new SubscriptionsAuthenticationParamsBasic().userName(USERNAME).password(PASSWORD);
567             subscriptionsAuthentication.setParamsBasic(basicParams);
568         } else if (authTypeEnum == SubscriptionsAuthentication.AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS) {
569             final SubscriptionsAuthenticationParamsOauth2ClientCredentials oathParams =
570                     new SubscriptionsAuthenticationParamsOauth2ClientCredentials().clientId(USERNAME)
571                             .clientPassword(PASSWORD).tokenEndpoint(TOKEN_ENDPOINT);
572             subscriptionsAuthentication.setParamsOauth2ClientCredentials(oathParams);
573         } else {
574             final SubscriptionsAuthenticationParamsBasic basicParams =
575                     new SubscriptionsAuthenticationParamsBasic().userName(USERNAME).password(PASSWORD);
576             subscriptionsAuthentication.setParamsBasic(basicParams);
577         }
578
579         return subscriptionsAuthentication;
580     }
581
582     private <T> ResponseEntity<ProblemDetails> sendHttpPost(final T notification) {
583         final String testURL = LOCALHOST_URL + port + NOTIFICATION_BASE_URL;
584         final HttpEntity<?> request = new HttpEntity<>(notification, basicHttpHeadersProvider.getHttpHeaders());
585         return testRestTemplate.withBasicAuth("test", "test").exchange(testURL, HttpMethod.POST, request,
586                 ProblemDetails.class);
587     }
588
589     private ResponseEntity<Void> sendHttpGet(final String url) {
590         final String testURL = LOCALHOST_URL + port + url;
591         final HttpEntity<?> request = new HttpEntity<>(basicHttpHeadersProvider.getHttpHeaders());
592         return testRestTemplate.withBasicAuth("test", "test").exchange(testURL, HttpMethod.GET, request, Void.class);
593     }
594
595 }