f1373bd4ea0e9c5bff2eea1da908bf310ffcfbb2
[so.git] / so-etsi-nfvo / so-etsi-nfvo-ns-lcm / so-etsi-nfvo-ns-lcm-bpmn-flows / src / test / java / org / onap / so / etsi / nfvo / ns / workflow / engine / tasks / InstantiateNsTaskTest.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 package org.onap.so.etsi.nfvo.ns.workflow.engine.tasks;
21
22 import static com.github.tomakehurst.wiremock.client.WireMock.get;
23 import static com.github.tomakehurst.wiremock.client.WireMock.notFound;
24 import static com.github.tomakehurst.wiremock.client.WireMock.ok;
25 import static com.github.tomakehurst.wiremock.client.WireMock.okJson;
26 import static com.github.tomakehurst.wiremock.client.WireMock.put;
27 import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
28 import static org.junit.Assert.assertEquals;
29 import static org.junit.Assert.assertNotNull;
30 import static org.junit.Assert.assertTrue;
31 import static org.onap.aaiclient.client.aai.AAIVersion.V19;
32 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME;
33 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogServiceProviderConfiguration.ETSI_CATALOG_REST_TEMPLATE_BEAN;
34 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterConfiguration.SOL003_ADAPTER_REST_TEMPLATE_BEAN;
35 import static org.springframework.test.web.client.ExpectedCount.times;
36 import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
37 import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
38 import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
39 import java.io.File;
40 import java.io.IOException;
41 import java.nio.file.Files;
42 import java.nio.file.Paths;
43 import java.time.LocalDateTime;
44 import java.util.ArrayList;
45 import java.util.HashMap;
46 import java.util.List;
47 import java.util.Map;
48 import java.util.Map.Entry;
49 import java.util.Optional;
50 import java.util.UUID;
51 import java.util.stream.Collectors;
52 import org.camunda.bpm.engine.history.HistoricProcessInstance;
53 import org.camunda.bpm.engine.history.HistoricVariableInstance;
54 import org.hamcrest.text.MatchesPattern;
55 import org.junit.After;
56 import org.junit.Before;
57 import org.junit.Test;
58 import org.onap.aaiclient.client.aai.entities.Results;
59 import org.onap.aaiclient.client.graphinventory.entities.Resource;
60 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse;
61 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStatusRetrievalStatusEnum;
62 import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo;
63 import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo;
64 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.BaseTest;
65 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider;
66 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor;
67 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service.JobExecutorService;
68 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob;
69 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst;
70 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
71 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc;
72 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.OperationStateEnum;
73 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
74 import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
75 import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest;
76 import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf;
77 import org.springframework.beans.factory.annotation.Autowired;
78 import org.springframework.beans.factory.annotation.Qualifier;
79 import org.springframework.http.HttpMethod;
80 import org.springframework.http.MediaType;
81 import org.springframework.http.converter.json.GsonHttpMessageConverter;
82 import org.springframework.test.web.client.MockRestServiceServer;
83 import org.springframework.web.client.RestTemplate;
84 import com.fasterxml.jackson.core.JsonProcessingException;
85 import com.fasterxml.jackson.databind.ObjectMapper;
86 import com.google.gson.Gson;
87
88 /**
89  * @author Andrew Lamb (andrew.a.lamb@est.tech)
90  * @author Waqas Ikram (waqas.ikram@est.tech)
91  *
92  */
93 public class InstantiateNsTaskTest extends BaseTest {
94
95     private static final String TENANT_ID = "6ca8680feba04dad9254f423c6e28e1c";
96     private static final String CLOUD_REGION = "regionOne";
97     private static final String CLOUD_OWNER = "CloudOwner";
98     private static final String UUID_REGEX =
99             "[0-9a-zA-Z]{8}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{4}\\-[0-9a-zA-Z]{12}";
100     private static final String VCPE_VBRGEMU_VNFD_ID = "b1bb0ce7-2222-4fa7-95ed-4840d70a1102";
101     private static final String VCPE_VBNG = "b1bb0ce7-2222-4fa7-95ed-4840d70a1101";
102     private static final String VCPE_INFRA_VNFD_ID = "b1bb0ce7-2222-4fa7-95ed-4840d70a1100";
103     private static final String VGMUX_VNFD_ID = "0408f076-e6c0-4c82-9940-272fddbb82de";
104     private static final String VGW_VNFD_ID = "3fca3543-07f5-492f-812c-ed462e4f94f4";
105     private static final String[] VCPE_VNFDS =
106             new String[] {VGW_VNFD_ID, VGMUX_VNFD_ID, VCPE_INFRA_VNFD_ID, VCPE_VBNG, VCPE_VBRGEMU_VNFD_ID};
107     private static final String SAMPLE_NSD_FILE = "src/test/resources/ns.csar";
108     private static final String NS_NAME = "InstantiateNetworkService";
109
110     @Autowired
111     private DatabaseServiceProvider databaseServiceProvider;
112
113     @Autowired
114     @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN)
115     private RestTemplate etsiCatalogRestTemplate;
116
117     @Autowired
118     @Qualifier(SOL003_ADAPTER_REST_TEMPLATE_BEAN)
119     private RestTemplate sol003AdapterRestTemplate;
120
121     private MockRestServiceServer mockEtsiCatalogRestServiceServer;
122
123     private MockRestServiceServer mockSol003AdapterRestServiceServer;
124
125     @Autowired
126     private JobExecutorService objUnderTest;
127
128     @Autowired
129     private GsonProvider gsonProvider;
130
131     private Gson gson;
132
133     private static final Map<String, String> VNFD_ID_TO_VNFPKG_ID_MAPPING = new HashMap<>();
134     static {
135         for (final String vnfd : VCPE_VNFDS) {
136             VNFD_ID_TO_VNFPKG_ID_MAPPING.put(vnfd, UUID.randomUUID().toString());
137         }
138     }
139
140     @Before
141     public void before() {
142         wireMockServer.resetAll();
143         gson = gsonProvider.getGson();
144
145         mockEtsiCatalogRestServiceServer =
146                 MockRestServiceServer.bindTo(etsiCatalogRestTemplate).ignoreExpectOrder(true).build();
147         mockSol003AdapterRestServiceServer =
148                 MockRestServiceServer.bindTo(sol003AdapterRestTemplate).ignoreExpectOrder(true).build();
149
150         etsiCatalogRestTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson));
151         sol003AdapterRestTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson));
152
153     }
154
155     @After
156     public void after() {
157         wireMockServer.resetAll();
158         mockEtsiCatalogRestServiceServer.reset();
159     }
160
161     @Test
162     public void testInstantiateNsWorkflow_JustUpdateStatus_SuccessfullCase() throws InterruptedException, IOException {
163         final String nsdId = UUID.randomUUID().toString();
164         final String nsdName = NS_NAME + "-" + System.currentTimeMillis();
165
166         final NfvoNsInst newNfvoNsInst = new NfvoNsInst().nsInstId(nsdId).name(nsdName)
167                 .nsPackageId(UUID.randomUUID().toString()).nsPackageId(nsdId).nsdId(nsdId).nsdInvariantId(nsdId)
168                 .status(State.NOT_INSTANTIATED).statusUpdatedTime(LocalDateTime.now());
169
170         databaseServiceProvider.saveNfvoNsInst(newNfvoNsInst);
171
172         mockSol003AdapterEndpoints();
173         mockAAIEndpoints(nsdId);
174         mockEtsiCatalogEndpoints(nsdId);
175
176         final String nsLcmOpOccId =
177                 objUnderTest.runInstantiateNsJob(newNfvoNsInst.getNsInstId(), getInstantiateNsRequest());
178
179         final Optional<NfvoJob> optional = getJobByResourceId(newNfvoNsInst.getNsInstId());
180         assertTrue(optional.isPresent());
181         final NfvoJob nfvoJob = optional.get();
182
183         assertTrue(waitForProcessInstanceToFinish(nfvoJob.getProcessInstanceId()));
184
185         final HistoricProcessInstance historicProcessInstance =
186                 getHistoricProcessInstance(nfvoJob.getProcessInstanceId());
187         assertNotNull(historicProcessInstance);
188
189         assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
190
191         // check if value in database has updated
192         final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsdId);
193         final NfvoNsInst nfvoNsInst = optionalNfvoNsInst.get();
194         assertEquals(State.INSTANTIATED, nfvoNsInst.getStatus());
195
196         final HistoricVariableInstance historicVariableInstance =
197                 getVariable(nfvoJob.getProcessInstanceId(), NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME);
198         assertNotNull(historicVariableInstance);
199         final NetworkServiceDescriptor nsd = (NetworkServiceDescriptor) historicVariableInstance.getValue();
200         assertNotNull(nsd);
201
202         assertEquals(VNFD_ID_TO_VNFPKG_ID_MAPPING.size(), nsd.getVnfs().size());
203
204         final List<NfvoNfInst> nfvoNfInsts = databaseServiceProvider.getNfvoNfInstByNsInstId(nsdId);
205         assertNotNull(nsd);
206         assertEquals(VNFD_ID_TO_VNFPKG_ID_MAPPING.size(), nfvoNfInsts.size());
207
208         final Optional<NsLcmOpOcc> optionalNsLcmOpOcc = databaseServiceProvider.getNsLcmOpOcc(nsLcmOpOccId);
209         assertTrue(optionalNsLcmOpOcc.isPresent());
210
211         assertEquals(OperationStateEnum.COMPLETED, optionalNsLcmOpOcc.get().getOperationState());
212
213         final Map<String, NfvoNfInst> nfvoNfInstsMap =
214                 nfvoNfInsts.stream().collect(Collectors.toMap(NfvoNfInst::getVnfdId, nfvoNfInst -> nfvoNfInst));
215
216         for (final Entry<String, String> entry : VNFD_ID_TO_VNFPKG_ID_MAPPING.entrySet()) {
217             assertTrue(nfvoNfInstsMap.containsKey(entry.getKey()));
218             assertEquals(State.INSTANTIATED, nfvoNfInstsMap.get(entry.getKey()).getStatus());
219
220         }
221
222     }
223
224     private void mockSol003AdapterEndpoints() {
225         mockSol003AdapterRestServiceServer
226                 .expect(times(VNFD_ID_TO_VNFPKG_ID_MAPPING.size()),
227                         requestTo(MatchesPattern.matchesPattern(SOL003_ADAPTER_ENDPOINT_URL + "/vnfs/.*")))
228                 .andExpect(method(HttpMethod.POST))
229                 .andRespond(withSuccess(gson.toJson(new CreateVnfResponse().jobId(UUID.randomUUID().toString())),
230                         MediaType.APPLICATION_JSON));
231
232         mockSol003AdapterRestServiceServer
233                 .expect(times(VNFD_ID_TO_VNFPKG_ID_MAPPING.size()),
234                         requestTo(MatchesPattern.matchesPattern(SOL003_ADAPTER_ENDPOINT_URL + "/jobs/.*")))
235                 .andExpect(method(HttpMethod.GET))
236                 .andRespond(withSuccess(gson.toJson(
237                         new org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse().operationState(
238                                 org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum.COMPLETED)
239                                 .operationStatusRetrievalStatus(OperationStatusRetrievalStatusEnum.STATUS_FOUND)),
240                         MediaType.APPLICATION_JSON));
241     }
242
243     private void mockEtsiCatalogEndpoints(final String nsdId) throws IOException {
244         mockEtsiCatalogRestServiceServer.expect(requestTo(ETSI_CATALOG_URL + "/nsd/v1/ns_descriptors/" + nsdId))
245                 .andExpect(method(HttpMethod.GET))
246                 .andRespond(withSuccess(gson.toJson(getNSPackageModel(nsdId)), MediaType.APPLICATION_JSON));
247         mockEtsiCatalogRestServiceServer
248                 .expect(requestTo(ETSI_CATALOG_URL + "/nsd/v1/ns_descriptors/" + nsdId + "/nsd_content"))
249                 .andExpect(method(HttpMethod.GET)).andRespond(withSuccess(
250                         getFileContent(getAbsolutePath(SAMPLE_NSD_FILE)), MediaType.APPLICATION_OCTET_STREAM));
251
252         for (final Entry<String, String> entry : VNFD_ID_TO_VNFPKG_ID_MAPPING.entrySet()) {
253             mockEtsiCatalogRestServiceServer
254                     .expect(requestTo(ETSI_CATALOG_URL + "/vnfpkgm/v1/vnf_packages/" + entry.getValue()))
255                     .andExpect(method(HttpMethod.GET)).andRespond(withSuccess(
256                             gson.toJson(getVnfPkgInfo(entry.getKey(), entry.getValue())), MediaType.APPLICATION_JSON));
257         }
258
259     }
260
261     private VnfPkgInfo getVnfPkgInfo(final String vnfdId, final String vnfPkgId) {
262         return new VnfPkgInfo().id(vnfPkgId).vnfdId(vnfdId);
263     }
264
265     private InstantiateNsRequest getInstantiateNsRequest() {
266         final Map<String, Object> additionalParams = new HashMap<>();
267         additionalParams.put("vim_id", CLOUD_OWNER + "_" + CLOUD_REGION + "_" + TENANT_ID);
268
269         final InstantiateNsRequest instantiateNsRequest = new InstantiateNsRequest().nsFlavourId("default");
270
271         for (final Entry<String, String> entry : VNFD_ID_TO_VNFPKG_ID_MAPPING.entrySet()) {
272             instantiateNsRequest
273                     .addAdditionalParamsForVnfItem(new NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf()
274                             .vnfProfileId(entry.getKey()).additionalParams(additionalParams));
275         }
276
277         return instantiateNsRequest;
278     }
279
280     private NsdInfo getNSPackageModel(final String nsdId) {
281         return new NsdInfo().id(nsdId).nsdId(nsdId).nsdInvariantId(NSD_INVARIANT_ID).nsdName("vcpe").nsdDesigner("ONAP")
282                 .vnfPkgIds(new ArrayList<>(VNFD_ID_TO_VNFPKG_ID_MAPPING.values()));
283     }
284
285     private byte[] getFileContent(final String path) throws IOException {
286         return Files.readAllBytes(Paths.get(path));
287     }
288
289
290     private String getAbsolutePath(final String path) {
291         return new File(path).getAbsolutePath();
292     }
293
294     private void mockAAIEndpoints(final String nsdId) throws JsonProcessingException {
295         final String modelEndpoint = "/aai/" + V19 + "/network/generic-vnfs/generic-vnf/" + UUID_REGEX;
296
297         wireMockServer.stubFor(
298                 get(urlMatching(modelEndpoint + "\\?resultIndex=0&resultSize=1&format=count")).willReturn(notFound()));
299
300         wireMockServer.stubFor(put(urlMatching(modelEndpoint)).willReturn(ok()));
301         wireMockServer.stubFor(put(urlMatching(modelEndpoint + "/relationship-list/relationship")).willReturn(ok()));
302
303         wireMockServer.stubFor(get(urlMatching(modelEndpoint)).willReturn(ok())
304                 .willReturn(okJson("{\"orchestration-status\": \"Created\"}")));
305
306         wireMockServer.stubFor(get(urlMatching("/aai/" + V19 + "/nodes/service-instances/service-instance/.*"))
307                 .willReturn(okJson(getResourceResultsResponseAsJson(nsdId))));
308
309         wireMockServer.stubFor(
310                 put(urlMatching("/aai/" + V19 + "/cloud-infrastructure/cloud-regions/cloud-region/" + CLOUD_OWNER + "/"
311                         + CLOUD_REGION + "/tenants/tenant/" + TENANT_ID + "/relationship-list/relationship"))
312                                 .willReturn(ok()));
313
314     }
315
316     private String getResourceResultsResponseAsJson(final String nsdId) throws JsonProcessingException {
317         final Resource resource = new Resource();
318         resource.setResourceType("service-instance");
319         resource.setResourceLink("/aai/" + V19 + "/business/customers/customer/" + GLOBAL_CUSTOMER_ID
320                 + "/service-subscriptions/service-subscription/NetworkService/service-instances/service-instance/"
321                 + nsdId);
322         final Results<Resource> results = new Results<>();
323         results.getResult().add(resource);
324         return new ObjectMapper().writeValueAsString(results);
325     }
326
327 }