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