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