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