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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.so.adapters.vnfmadapter.rest;
23 import static org.hamcrest.Matchers.is;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertNotEquals;
26 import static org.junit.Assert.assertNotNull;
27 import static org.junit.Assert.assertNull;
28 import static org.junit.Assert.assertThat;
29 import static org.junit.Assert.assertTrue;
30 import static org.onap.so.adapters.vnfmadapter.Constants.PACKAGE_MANAGEMENT_BASE_URL;
31 import static org.onap.so.client.RestTemplateConfig.CONFIGURABLE_REST_TEMPLATE;
32 import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
33 import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
34 import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
35 import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
38 import java.net.URISyntaxException;
39 import java.nio.file.Files;
40 import java.nio.file.Paths;
41 import java.security.GeneralSecurityException;
42 import java.util.ArrayList;
43 import java.util.List;
44 import java.util.Objects;
45 import java.util.UUID;
46 import org.junit.After;
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 import org.onap.so.adapters.vnfmadapter.Constants;
51 import org.onap.so.adapters.vnfmadapter.VnfmAdapterApplication;
52 import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.model.BasicAuth;
53 import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.model.LinkSelf;
54 import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.model.NsdmSubscription;
55 import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.model.PkgmNotificationsFilter;
56 import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.model.PkgmSubscription;
57 import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.model.ProblemDetails;
58 import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.model.SubscriptionAuthentication;
59 import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.model.Version;
60 import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.model.VnfProducts;
61 import org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.model.VnfProductsProviders;
62 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.InlineResponse2002;
63 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.InlineResponse201;
64 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.PkgmSubscriptionRequest;
65 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsAuthentication;
66 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsFilter1;
67 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsFilterVnfProductsFromProviders;
68 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsLinks;
69 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.VnfPackagesLinksSelf;
70 import org.springframework.beans.factory.annotation.Autowired;
71 import org.springframework.beans.factory.annotation.Qualifier;
72 import org.springframework.boot.test.context.SpringBootTest;
73 import org.springframework.boot.test.web.client.TestRestTemplate;
74 import org.springframework.boot.web.server.LocalServerPort;
75 import org.springframework.cache.Cache;
76 import org.springframework.cache.CacheManager;
77 import org.springframework.http.HttpHeaders;
78 import org.springframework.http.HttpMethod;
79 import org.springframework.http.HttpStatus;
80 import org.springframework.http.MediaType;
81 import org.springframework.http.ResponseEntity;
82 import org.springframework.test.context.ActiveProfiles;
83 import org.springframework.test.context.junit4.SpringRunner;
84 import org.springframework.test.web.client.MockRestServiceServer;
85 import org.springframework.test.web.client.match.MockRestRequestMatchers;
86 import org.springframework.web.client.RestTemplate;
87 import com.google.gson.Gson;
90 * @author Ronan Kenny (ronan.kenny@est.tech)
91 * @author Gareth Roper (gareth.roper@est.tech)
93 @RunWith(SpringRunner.class)
94 @SpringBootTest(classes = VnfmAdapterApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
95 @ActiveProfiles("test")
96 public class Sol003PackageManagementSubscriptionControllerTest {
98 private final Gson gson = new Gson();
99 private final URI msbEndpoint = URI.create("http://msb-iag.onap:80/api/vnfpkgm/v1/subscriptions");
100 private static final String _NOTIFICATION_CALLBACK_URI =
101 "https://so-vnfm-adapter.onap:30406" + Constants.ETSI_SUBSCRIPTION_NOTIFICATION_BASE_URL;
102 private static final String LOCALHOST_URL = "http://localhost:";
105 @Qualifier(CONFIGURABLE_REST_TEMPLATE)
106 private RestTemplate restTemplate;
107 private MockRestServiceServer mockRestServiceServer;
109 private CacheManager cacheServiceProvider;
111 private Sol003PackageManagementSubscriptionController sol003PackageManagementSubscriptionController;
114 private TestRestTemplate testRestTemplate;
119 private static final String ID = UUID.randomUUID().toString();
122 public void setUp() {
123 mockRestServiceServer = MockRestServiceServer.bindTo(restTemplate).build();
124 final Cache cache = cacheServiceProvider.getCache(Constants.PACKAGE_MANAGEMENT_SUBSCRIPTION_CACHE);
129 public void after() {
130 mockRestServiceServer.reset();
134 public void testSuccessPostSubscription() throws GeneralSecurityException, URISyntaxException {
135 final PkgmSubscriptionRequest pkgmSubscriptionRequest = postSubscriptionForTest();
136 final ResponseEntity<InlineResponse201> response =
137 (ResponseEntity<InlineResponse201>) sol003PackageManagementSubscriptionController
138 .postSubscriptionRequest(pkgmSubscriptionRequest);
140 final HttpHeaders headers = buildHttpHeaders(Objects.requireNonNull(response.getBody()).getCallbackUri());
142 final SubscriptionsLinks subscriptionsLinks = new SubscriptionsLinks();
143 final VnfPackagesLinksSelf vnfPackagesLinksSelf = new VnfPackagesLinksSelf();
144 vnfPackagesLinksSelf.setHref("https://so-vnfm-adapter.onap:30406" + PACKAGE_MANAGEMENT_BASE_URL
145 + "/subscriptions/" + response.getBody().getId());
146 subscriptionsLinks.setSelf(vnfPackagesLinksSelf);
148 assertEquals(pkgmSubscriptionRequest.getFilter(), response.getBody().getFilter());
149 assertEquals(subscriptionsLinks, response.getBody().getLinks());
150 assertEquals(response.getBody().getFilter(), pkgmSubscriptionRequest.getFilter());
151 assert (response.getHeaders().equals(headers));
152 assertThat(response.getStatusCode(), is(HttpStatus.CREATED));
153 assertNotNull(response.getBody().getCallbackUri());
157 public void testFailPostSubscriptionAlreadyExists() throws GeneralSecurityException {
158 final PkgmSubscriptionRequest pkgmSubscriptionRequest = postSubscriptionForTest();
160 final ResponseEntity<InlineResponse2002> response =
161 (ResponseEntity<InlineResponse2002>) sol003PackageManagementSubscriptionController
162 .postSubscriptionRequest(pkgmSubscriptionRequest);
164 // Create duplicate entry
165 final PkgmSubscriptionRequest pkgmSubscriptionRequest2 = buildPkgmSubscriptionRequest();
167 final ResponseEntity<InlineResponse2002> response2002 =
168 (ResponseEntity<InlineResponse2002>) sol003PackageManagementSubscriptionController
169 .postSubscriptionRequest(pkgmSubscriptionRequest2);
171 assertEquals(HttpStatus.SEE_OTHER, response2002.getStatusCode());
175 public void testSuccessGetSubscriptionWithSubscriptionId() throws GeneralSecurityException, URISyntaxException {
177 final PkgmSubscriptionRequest pkgmSubscriptionRequest = postSubscriptionForTest();
179 mockRestServiceServer.expect(requestTo(msbEndpoint + "/" + ID)).andExpect(method(HttpMethod.GET))
180 .andRespond(withSuccess(gson.toJson(new NsdmSubscription().id(ID)), MediaType.APPLICATION_JSON));
182 final ResponseEntity<InlineResponse201> response =
183 (ResponseEntity<InlineResponse201>) sol003PackageManagementSubscriptionController
184 .postSubscriptionRequest(pkgmSubscriptionRequest);
185 final String subscriptionId = response.getBody().getId();
189 final ResponseEntity<InlineResponse201> responseEntity =
190 (ResponseEntity<InlineResponse201>) sol003PackageManagementSubscriptionController
191 .getSubscription(subscriptionId);
193 final HttpHeaders headers = buildHttpHeaders(response.getBody().getCallbackUri());
195 assertEquals(response.getBody().getFilter(), pkgmSubscriptionRequest.getFilter());
196 assertEquals(response.getHeaders(), headers);
197 assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
198 assertEquals(pkgmSubscriptionRequest.getFilter(), response.getBody().getFilter());
199 // Ensure CallBackUri is set to new URI
200 assertNotEquals(pkgmSubscriptionRequest.getCallbackUri(), response.getBody().getCallbackUri());
204 public void testFailGetSubscriptionWithInvalidSubscriptionId() {
205 final String invalidId = "invalidSubscriptionId";
206 mockRestServiceServer.expect(requestTo(msbEndpoint + "/" + invalidId)).andExpect(method(HttpMethod.GET))
207 .andRespond(withStatus(HttpStatus.NOT_FOUND));
208 final ResponseEntity<?> response = sol003PackageManagementSubscriptionController.getSubscription(invalidId);
209 assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
210 assertTrue(response.getBody() instanceof ProblemDetails);
214 public void testSuccessGetSubscriptions() throws GeneralSecurityException {
215 final PkgmSubscription pkgmSubscription = buildPkgmSubscription();
216 final PkgmSubscriptionRequest pkgmSubscriptionRequest = buildPkgmSubscriptionRequest();
218 mockRestServiceServer.expect(requestTo(msbEndpoint)).andExpect(method(HttpMethod.POST))
219 .andRespond(withSuccess(gson.toJson(pkgmSubscription), MediaType.APPLICATION_JSON));
220 mockRestServiceServer.expect(requestTo(msbEndpoint + "/" + ID)).andExpect(method(HttpMethod.GET))
221 .andRespond(withSuccess(gson.toJson(new NsdmSubscription().id(ID)), MediaType.APPLICATION_JSON));
223 sol003PackageManagementSubscriptionController.postSubscriptionRequest(pkgmSubscriptionRequest);
224 final ResponseEntity<List<InlineResponse201>> response =
225 sol003PackageManagementSubscriptionController.getSubscriptions();
227 final List<InlineResponse201> subscriptionsList = response.getBody();
229 assertEquals(Objects.requireNonNull(response.getBody()).get(0).getFilter(),
230 pkgmSubscriptionRequest.getFilter());
231 assertNotNull(subscriptionsList != null);
232 assertNotEquals('0', subscriptionsList.size());
233 assertEquals(HttpStatus.OK, response.getStatusCode());
237 public void testSuccessDeleteSubscriptionWithSubscriptionId() throws GeneralSecurityException {
238 final PkgmSubscriptionRequest pkgmSubscriptionRequest = buildPkgmSubscriptionRequest();
239 final PkgmSubscription pkgmSubscription = buildPkgmSubscription();
240 final String subscriptionId = pkgmSubscription.getId();
242 mockRestServiceServer.expect(requestTo(msbEndpoint)).andExpect(method(HttpMethod.POST))
243 .andRespond(withSuccess(gson.toJson(pkgmSubscription), MediaType.APPLICATION_JSON));
245 mockRestServiceServer.expect(requestTo(msbEndpoint + "/" + subscriptionId)).andExpect(method(HttpMethod.DELETE))
246 .andRespond(withStatus(HttpStatus.NO_CONTENT));
247 mockRestServiceServer.expect(requestTo(msbEndpoint + "/" + subscriptionId)).andExpect(method(HttpMethod.GET))
248 .andRespond(withSuccess(gson.toJson(new NsdmSubscription().id(subscriptionId)),
249 MediaType.APPLICATION_JSON));
251 final ResponseEntity<InlineResponse2002> responsePost =
252 (ResponseEntity<InlineResponse2002>) sol003PackageManagementSubscriptionController
253 .postSubscriptionRequest(pkgmSubscriptionRequest);
255 final ResponseEntity responseDelete =
256 sol003PackageManagementSubscriptionController.deleteSubscription(subscriptionId);
258 // Attempt to retrieve the subscription after delete
259 final ResponseEntity<InlineResponse2002> responseGetSubscription =
260 (ResponseEntity<InlineResponse2002>) sol003PackageManagementSubscriptionController
261 .getSubscription(subscriptionId);
263 assertEquals(HttpStatus.NOT_FOUND, responseGetSubscription.getStatusCode());
264 assertEquals(HttpStatus.NO_CONTENT, responseDelete.getStatusCode());
268 public void testDeleteSubscription_SubscripitonNotFoundInEtsiCatalogManager_SubscriptionDeletedFromLocalCache()
269 throws GeneralSecurityException {
270 final PkgmSubscriptionRequest pkgmSubscriptionRequest = buildPkgmSubscriptionRequest();
271 final PkgmSubscription pkgmSubscription = buildPkgmSubscription();
273 mockRestServiceServer.expect(requestTo(msbEndpoint)).andExpect(method(HttpMethod.POST))
274 .andRespond(withSuccess(gson.toJson(pkgmSubscription), MediaType.APPLICATION_JSON));
276 mockRestServiceServer.expect(requestTo(msbEndpoint + "/" + ID)).andExpect(method(HttpMethod.DELETE))
277 .andRespond(withStatus(HttpStatus.NOT_FOUND));
279 final ResponseEntity<InlineResponse2002> responsePost =
280 (ResponseEntity<InlineResponse2002>) sol003PackageManagementSubscriptionController
281 .postSubscriptionRequest(pkgmSubscriptionRequest);
283 final Cache cache = cacheServiceProvider.getCache(Constants.PACKAGE_MANAGEMENT_SUBSCRIPTION_CACHE);
284 assertNotNull(cache.get(ID));
286 final ResponseEntity responseDelete = sol003PackageManagementSubscriptionController.deleteSubscription(ID);
288 assertEquals(HttpStatus.NO_CONTENT, responseDelete.getStatusCode());
289 assertNull(cache.get(ID));
294 public void testFailDeleteSubscriptionWithInvalidSubscriptionId() throws URISyntaxException, InterruptedException {
295 final ResponseEntity<Void> responseDelete = (ResponseEntity<Void>) sol003PackageManagementSubscriptionController
296 .deleteSubscription("invalidSubscriptionId");
297 assertEquals(HttpStatus.NOT_FOUND, responseDelete.getStatusCode());
302 public void testSuccessPostSubscriptionWithValidNotificationTypes() throws Exception {
304 final String file = getAbsolutePath("src/test/resources/requests/SubscriptionRequest.json");
305 final String json = new String(Files.readAllBytes(Paths.get(file)));
306 final PkgmSubscriptionRequest request = gson.fromJson(json, PkgmSubscriptionRequest.class);
308 mockRestServiceServer.expect(requestTo(msbEndpoint)).andExpect(method(HttpMethod.POST))
309 .andExpect(MockRestRequestMatchers.content().json(gson.toJson(getEtsiCatalogPkgmSubscriptionRequest())))
310 .andRespond(withSuccess(gson.toJson(buildPkgmSubscription()), MediaType.APPLICATION_JSON));
313 final ResponseEntity<InlineResponse201> responseEntity = testRestTemplate.postForEntity(
314 LOCALHOST_URL + port + Constants.PACKAGE_MANAGEMENT_BASE_URL + "/subscriptions", request,
315 InlineResponse201.class);
317 assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode());
318 assertTrue(responseEntity.hasBody());
319 final InlineResponse201 actual = responseEntity.getBody();
320 assertEquals(ID, actual.getId());
325 private org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.model.PkgmSubscriptionRequest getEtsiCatalogPkgmSubscriptionRequest() {
326 return new org.onap.so.adapters.vnfmadapter.extclients.etsicatalog.model.PkgmSubscriptionRequest()
327 .filters(new PkgmNotificationsFilter()
328 .addNotificationTypesItem(
329 PkgmNotificationsFilter.NotificationTypesEnum.VNFPACKAGEONBOARDINGNOTIFICATION)
330 .addVnfdIdItem("VNFDID").addVnfPkgIdItem("VNFPKGID")
331 .addOperationalStateItem(PkgmNotificationsFilter.OperationalStateEnum.ENABLED)
332 .addVnfProductsFromProvidersItem(new VnfProductsProviders().vnfProvider("EST")
333 .addVnfProductsItem(new VnfProducts().vnfProductName("VnfProducts")
334 .addVersionsItem(new Version().vnfSoftwareVersion("vnfSoftwareVersion")
335 .addVnfdVersionsItem("version1")))))
336 .callbackUri(_NOTIFICATION_CALLBACK_URI).authentication(
337 new SubscriptionAuthentication().addAuthTypeItem(SubscriptionAuthentication.AuthTypeEnum.BASIC)
338 .paramsBasic(new BasicAuth().userName("vnfm").password("password1$")));
341 private PkgmSubscriptionRequest buildPkgmSubscriptionRequest() {
342 final PkgmSubscriptionRequest pkgmSubscriptionRequest = new PkgmSubscriptionRequest();
343 final SubscriptionsFilter1 sub = buildSubscriptionsFilter();
344 final SubscriptionsAuthentication auth = new SubscriptionsAuthentication();
345 pkgmSubscriptionRequest.setFilter(sub);
346 pkgmSubscriptionRequest.setCallbackUri(msbEndpoint.toString());
347 pkgmSubscriptionRequest.setAuthentication(auth);
348 return pkgmSubscriptionRequest;
351 private SubscriptionsFilter1 buildSubscriptionsFilter() {
352 final SubscriptionsFilter1 sub = new SubscriptionsFilter1();
353 final List<String> vnfdIdList = new ArrayList<>();
354 final List<String> vnfPkgIdList = new ArrayList<>();
355 final List<SubscriptionsFilter1.NotificationTypesEnum> notificationTypes = new ArrayList<>();
356 final SubscriptionsFilterVnfProductsFromProviders subscriptionsFilterVnfProductsFromProviders =
357 new SubscriptionsFilterVnfProductsFromProviders();
358 final List<SubscriptionsFilterVnfProductsFromProviders> vnfProductsFromProviders = new ArrayList<>();
360 vnfProductsFromProviders.add(subscriptionsFilterVnfProductsFromProviders);
361 sub.setVnfdId(vnfdIdList);
362 sub.setNotificationTypes(notificationTypes);
363 sub.setVnfPkgId(vnfPkgIdList);
364 sub.setVnfProductsFromProviders(vnfProductsFromProviders);
368 private PkgmSubscription buildPkgmSubscription() {
369 final PkgmSubscription pkgmSubscription = new PkgmSubscription();
370 final PkgmNotificationsFilter pkgmNotificationsFilter = new PkgmNotificationsFilter();
371 final LinkSelf linkSelf = new LinkSelf();
373 pkgmSubscription.setId(ID);
374 pkgmSubscription.setCallbackUri(msbEndpoint + "/" + pkgmSubscription.getId().toString());
375 pkgmSubscription.setFilter(pkgmNotificationsFilter);
376 pkgmSubscription.setLinks(linkSelf);
377 return pkgmSubscription;
380 private PkgmSubscriptionRequest postSubscriptionForTest() {
381 final PkgmSubscriptionRequest pkgmSubscriptionRequest = buildPkgmSubscriptionRequest();
382 final PkgmSubscription pkgmSubscription = buildPkgmSubscription();
384 mockRestServiceServer.expect(requestTo(msbEndpoint)).andExpect(method(HttpMethod.POST))
385 .andRespond(withSuccess(gson.toJson(pkgmSubscription), MediaType.APPLICATION_JSON));
386 return pkgmSubscriptionRequest;
389 private HttpHeaders buildHttpHeaders(final String uri) throws URISyntaxException {
390 final HttpHeaders headers = new HttpHeaders();
391 final URI myUri = new URI(uri);
392 headers.setLocation(myUri);
396 private String getAbsolutePath(final String path) {
397 final File file = new File(path);
398 return file.getAbsolutePath();