2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2023 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=========================================================
20 package org.onap.so.cnfm.lcm.bpmn.flows.tasks;
22 import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
23 import static com.github.tomakehurst.wiremock.client.WireMock.get;
24 import static com.github.tomakehurst.wiremock.client.WireMock.notFound;
25 import static com.github.tomakehurst.wiremock.client.WireMock.ok;
26 import static com.github.tomakehurst.wiremock.client.WireMock.okJson;
27 import static com.github.tomakehurst.wiremock.client.WireMock.put;
28 import static com.github.tomakehurst.wiremock.client.WireMock.serverError;
29 import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
30 import static org.junit.Assert.assertEquals;
31 import static org.junit.Assert.assertFalse;
32 import static org.junit.Assert.assertNotNull;
33 import static org.junit.Assert.assertNull;
34 import static org.junit.Assert.assertTrue;
35 import static org.onap.aaiclient.client.aai.AAIVersion.V19;
36 import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_AS_RESPONSE_PARAM_NAME;
37 import static org.onap.so.cnfm.lcm.model.utils.AdditionalParamsConstants.CLOUD_OWNER_PARAM_KEY;
38 import static org.onap.so.cnfm.lcm.model.utils.AdditionalParamsConstants.CLOUD_REGION_PARAM_KEY;
39 import static org.onap.so.cnfm.lcm.model.utils.AdditionalParamsConstants.RESOURCE_ID_KEY;
40 import static org.onap.so.cnfm.lcm.model.utils.AdditionalParamsConstants.SERVICE_INSTANCE_ID_PARAM_KEY;
41 import static org.onap.so.cnfm.lcm.model.utils.AdditionalParamsConstants.SERVICE_INSTANCE_NAME_PARAM_KEY;
42 import static org.onap.so.cnfm.lcm.model.utils.AdditionalParamsConstants.TENANT_ID_PARAM_KEY;
43 import static org.springframework.http.HttpHeaders.ACCEPT;
44 import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE;
46 import java.io.IOException;
47 import java.nio.file.Files;
48 import java.nio.file.Path;
49 import java.time.LocalDateTime;
51 import java.util.Optional;
52 import java.util.UUID;
53 import org.camunda.bpm.engine.history.HistoricProcessInstance;
54 import org.camunda.bpm.engine.history.HistoricVariableInstance;
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.cnfm.lcm.bpmn.flows.BaseTest;
61 import org.onap.so.cnfm.lcm.bpmn.flows.exceptions.AsRequestProcessingException;
62 import org.onap.so.cnfm.lcm.bpmn.flows.service.JobExecutorService;
63 import org.onap.so.cnfm.lcm.bpmn.flows.service.WorkflowQueryService;
64 import org.onap.so.cnfm.lcm.database.beans.AsInst;
65 import org.onap.so.cnfm.lcm.database.beans.Job;
66 import org.onap.so.cnfm.lcm.database.beans.JobStatusEnum;
67 import org.onap.so.cnfm.lcm.database.beans.State;
68 import org.onap.so.cnfm.lcm.model.AsInstance;
69 import org.onap.so.cnfm.lcm.model.AsInstance.InstantiationStateEnum;
70 import org.onap.so.cnfm.lcm.model.CreateAsRequest;
71 import org.onap.so.cnfm.lcm.model.ErrorDetails;
72 import org.springframework.beans.factory.annotation.Autowired;
73 import org.springframework.http.HttpStatus;
74 import com.fasterxml.jackson.core.JsonProcessingException;
75 import com.fasterxml.jackson.databind.ObjectMapper;
78 * @author Waqas Ikram (waqas.ikram@est.tech)
81 public class CreateAsTaskTest extends BaseTest {
82 private static final String DUMMY_VALUE = "DUMMY_VALUE";
83 private static final String SRC_TEST_DIR = "src/test/resources";
84 private static final String TENAT_ID = UUID.randomUUID().toString();
85 private static final String CLOUD_OWNER = "CloudOwner";
86 private static final String CLOUD_REGION = "CloudRegion";
87 private static final String ASD_ID = UUID.randomUUID().toString();
88 private static final String AS_NAME = "CreateAsService-" + ASD_ID;
89 private static final String RESOURCE_ASD_PACKAGE_CSAR_PATH =
90 SRC_TEST_DIR + "/resource-Generatedasdpackage-csar.csar";
93 private JobExecutorService objUnderTest;
96 private WorkflowQueryService workflowQueryService;
99 public void before() {
100 wireMockServer.resetAll();
104 public void after() {
105 wireMockServer.resetAll();
109 public void testCreateAsWorkflow_SuccessfullCase() throws InterruptedException, IOException {
111 mockSdcResourceEndpoint(ASD_ID);
113 final CreateAsRequest createAsRequest = getCreateAsRequest();
117 final AsInstance nsResponse = objUnderTest.runCreateAsJob(createAsRequest);
118 assertNotNull(nsResponse);
119 assertNotNull(nsResponse.getAsInstanceid());
121 final Optional<Job> optional = getJobByResourceId(createAsRequest.getAsdId());
122 assertTrue(optional.isPresent());
123 final Job job = optional.get();
125 assertTrue(waitForProcessInstanceToFinish(job.getProcessInstanceId()));
127 final HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance(job.getProcessInstanceId());
128 assertNotNull(historicProcessInstance);
130 assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
131 assertTrue(databaseServiceProvider.isAsInstExists(createAsRequest.getAsInstanceName()));
133 final Job actualJob = optional.get();
134 assertEquals(JobStatusEnum.FINISHED, actualJob.getStatus());
136 assertEquals(AS_NAME, nsResponse.getAsInstanceName());
137 assertEquals(InstantiationStateEnum.NOT_INSTANTIATED, nsResponse.getInstantiationState());
139 final HistoricVariableInstance doesNsPackageExistsVar =
140 getVariable(job.getProcessInstanceId(), "doesAsPackageExists");
141 assertNotNull(doesNsPackageExistsVar);
142 assertTrue((boolean) doesNsPackageExistsVar.getValue());
144 final HistoricVariableInstance doesNsInstanceExistsVar =
145 getVariable(job.getProcessInstanceId(), "doesAsInstanceExists");
146 assertNotNull(doesNsInstanceExistsVar);
147 assertFalse((boolean) doesNsInstanceExistsVar.getValue());
152 public void testCreateAsWorkflow_FailsToGetAsPackage() throws InterruptedException {
153 final String asdId = UUID.randomUUID().toString();
154 final String asName = AS_NAME + "-" + System.currentTimeMillis();
156 final CreateAsRequest createAsRequest = getCreateAsRequest(asdId, asName);
158 wireMockServer.stubFor(
159 get(getSdcResourceUrl(asdId)).willReturn(aResponse().withStatus(HttpStatus.NOT_FOUND.value())));
161 objUnderTest.runCreateAsJob(createAsRequest);
162 } catch (final Exception exception) {
163 assertEquals(AsRequestProcessingException.class, exception.getClass());
166 final Optional<Job> optional = getJobByResourceId(createAsRequest.getAsdId());
167 assertTrue(optional.isPresent());
168 final Job job = optional.get();
170 assertTrue(waitForProcessInstanceToFinish(job.getProcessInstanceId()));
172 final HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance(job.getProcessInstanceId());
173 assertNotNull(historicProcessInstance);
175 assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
177 final HistoricVariableInstance nsResponseVariable =
178 getVariable(job.getProcessInstanceId(), CREATE_AS_RESPONSE_PARAM_NAME);
179 assertNull(nsResponseVariable);
181 final Optional<ErrorDetails> errorDetailsOptional =
182 workflowQueryService.getErrorDetails(job.getProcessInstanceId());
183 assertTrue(errorDetailsOptional.isPresent());
185 final ErrorDetails errorDetails = errorDetailsOptional.get();
186 assertNotNull(errorDetails);
187 assertNotNull(errorDetails.getDetail());
189 final HistoricVariableInstance doesAsPackageExistsVar =
190 getVariable(job.getProcessInstanceId(), "doesAsPackageExists");
191 assertNotNull(doesAsPackageExistsVar);
192 assertFalse((boolean) doesAsPackageExistsVar.getValue());
197 public void testCreateAsWorkflow_AsInstanceExistsInDb() throws IOException, InterruptedException {
198 final String asdId = UUID.randomUUID().toString();
199 final String asName = AS_NAME + "-" + System.currentTimeMillis();
201 mockSdcResourceEndpoint(asdId);
203 final CreateAsRequest createAsRequest = getCreateAsRequest(asdId, asName);
205 databaseServiceProvider.saveAsInst(new AsInst().asdId(asdId).name(createAsRequest.getAsInstanceName())
206 .asPackageId(UUID.randomUUID().toString()).asdInvariantId(asdId).asProvider(DUMMY_VALUE)
207 .asApplicationName(DUMMY_VALUE).asApplicationVersion(DUMMY_VALUE).serviceInstanceId(DUMMY_VALUE)
208 .serviceInstanceName(DUMMY_VALUE).cloudOwner(DUMMY_VALUE).cloudRegion(DUMMY_VALUE).tenantId(DUMMY_VALUE)
209 .status(State.INSTANTIATED).statusUpdatedTime(LocalDateTime.now()));
212 objUnderTest.runCreateAsJob(createAsRequest);
213 } catch (final Exception exception) {
214 assertEquals(AsRequestProcessingException.class, exception.getClass());
217 final Optional<Job> optional = getJobByResourceId(createAsRequest.getAsdId());
218 assertTrue(optional.isPresent());
219 final Job job = optional.get();
220 assertEquals(JobStatusEnum.ERROR, job.getStatus());
222 assertTrue(waitForProcessInstanceToFinish(job.getProcessInstanceId()));
224 final HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance(job.getProcessInstanceId());
225 assertNotNull(historicProcessInstance);
226 assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
228 assertTrue(databaseServiceProvider.isAsInstExists(createAsRequest.getAsInstanceName()));
230 final Optional<ErrorDetails> errorDetailsOptional =
231 workflowQueryService.getErrorDetails(job.getProcessInstanceId());
232 assertTrue(errorDetailsOptional.isPresent());
234 final ErrorDetails errorDetails = errorDetailsOptional.get();
235 assertNotNull(errorDetails);
236 assertNotNull(errorDetails.getDetail());
238 final HistoricVariableInstance doesAsInstanceExistsVar =
239 getVariable(job.getProcessInstanceId(), "doesAsInstanceExists");
240 assertNotNull(doesAsInstanceExistsVar);
241 assertTrue((boolean) doesAsInstanceExistsVar.getValue());
246 public void testCreateAsWorkflow_FailToCreateResouceInAai() throws InterruptedException, IOException {
247 final String asdId = UUID.randomUUID().toString();
248 final String asName = AS_NAME + "-" + System.currentTimeMillis();
249 final String resourceId = UUID.randomUUID().toString();
251 mockSdcResourceEndpoint(asdId);
253 final CreateAsRequest createAsRequest = getCreateAsRequest(asdId, asName, resourceId);
256 final String modelEndpoint = "/aai/" + V19 + "/network/generic-vnfs/generic-vnf/" + resourceId;
257 wireMockServer.stubFor(
258 get(urlMatching(modelEndpoint + "\\?resultIndex=0&resultSize=1&format=count")).willReturn(notFound()));
259 wireMockServer.stubFor(put(urlMatching(modelEndpoint)).willReturn(serverError()));
262 objUnderTest.runCreateAsJob(createAsRequest);
263 } catch (final Exception exception) {
264 assertEquals(AsRequestProcessingException.class, exception.getClass());
267 final Optional<Job> optional = getJobByResourceId(createAsRequest.getAsdId());
268 assertTrue(optional.isPresent());
269 final Job job = optional.get();
271 assertTrue(waitForProcessInstanceToFinish(job.getProcessInstanceId()));
273 final HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance(job.getProcessInstanceId());
274 assertNotNull(historicProcessInstance);
276 assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
277 assertTrue(databaseServiceProvider.isAsInstExists(createAsRequest.getAsInstanceName()));
279 final Optional<ErrorDetails> errorDetailsOptional =
280 workflowQueryService.getErrorDetails(job.getProcessInstanceId());
281 assertTrue(errorDetailsOptional.isPresent());
283 final ErrorDetails errorDetails = errorDetailsOptional.get();
284 assertNotNull(errorDetails);
285 assertNotNull(errorDetails.getDetail());
289 private void mockSdcResourceEndpoint(final String asdId) throws IOException {
290 wireMockServer.stubFor(get(getSdcResourceUrl(asdId))
291 .willReturn(aResponse().withBody(getFileContent(getAbsolutePath(RESOURCE_ASD_PACKAGE_CSAR_PATH)))
292 .withHeader(ACCEPT, APPLICATION_OCTET_STREAM_VALUE)));
295 private CreateAsRequest getCreateAsRequest() {
296 return getCreateAsRequest(ASD_ID, AS_NAME);
299 private String getSdcResourceUrl(final String asdId) {
300 return "/sdc/v1/catalog/resources/" + asdId + "/toscaModel";
303 private CreateAsRequest getCreateAsRequest(final String asdId, final String asName) {
304 final Map<String, Object> additionalParams = Map.of(SERVICE_INSTANCE_ID_PARAM_KEY, SERVICE_INSTANCE_ID,
305 SERVICE_INSTANCE_NAME_PARAM_KEY, SERVICE_INSTANCE_NAME, CLOUD_OWNER_PARAM_KEY, CLOUD_OWNER,
306 CLOUD_REGION_PARAM_KEY, CLOUD_REGION, TENANT_ID_PARAM_KEY, TENAT_ID);
308 return getCreateAsRequest(asdId, asName, additionalParams);
311 private CreateAsRequest getCreateAsRequest(final String asdId, final String asName, final String resourceId) {
312 final Map<String, Object> additionalParams = Map.of(SERVICE_INSTANCE_ID_PARAM_KEY, SERVICE_INSTANCE_ID,
313 SERVICE_INSTANCE_NAME_PARAM_KEY, SERVICE_INSTANCE_NAME, CLOUD_OWNER_PARAM_KEY, CLOUD_OWNER,
314 CLOUD_REGION_PARAM_KEY, CLOUD_REGION, TENANT_ID_PARAM_KEY, TENAT_ID, RESOURCE_ID_KEY, resourceId);
316 return getCreateAsRequest(asdId, asName, additionalParams);
319 private CreateAsRequest getCreateAsRequest(final String asdId, final String asName,
320 final Map<String, Object> additionalParams) {
321 return new CreateAsRequest().asdId(asdId).asInstanceName(asName).additionalParams(additionalParams);
324 private void mockAAIEndpoints() throws JsonProcessingException {
325 final String modelEndpoint = "/aai/" + V19 + "/network/generic-vnfs/generic-vnf/" + UUID_REGEX;
327 wireMockServer.stubFor(
328 get(urlMatching(modelEndpoint + "\\?resultIndex=0&resultSize=1&format=count")).willReturn(notFound()));
330 wireMockServer.stubFor(put(urlMatching(modelEndpoint)).willReturn(ok()));
331 wireMockServer.stubFor(put(urlMatching(modelEndpoint + "/relationship-list/relationship")).willReturn(ok()));
333 wireMockServer.stubFor(get(urlMatching(modelEndpoint)).willReturn(ok())
334 .willReturn(okJson("{\"orchestration-status\": \"Created\"}")));
336 wireMockServer.stubFor(get(urlMatching("/aai/" + V19 + "/nodes/service-instances/service-instance/.*"))
337 .willReturn(okJson(getResourceResultsResponseAsJson(SERVICE_INSTANCE_ID))));
339 wireMockServer.stubFor(put(urlMatching("/aai/" + V19 + "/cloud-infrastructure/cloud-regions/cloud-region/"
340 + CLOUD_OWNER + "/" + CLOUD_REGION + "/tenants/tenant/" + TENAT_ID + "/relationship-list/relationship"))
345 private String getResourceResultsResponseAsJson(final String nsdId) throws JsonProcessingException {
346 final Resource resource = new Resource();
347 resource.setResourceType("service-instance");
348 resource.setResourceLink("/aai/" + V19 + "/business/customers/customer/GLOBAL_CUSTOMER_ID"
349 + "/service-subscriptions/service-subscription/NetworkService/service-instances/service-instance/"
351 final Results<Resource> results = new Results<>();
352 results.getResult().add(resource);
353 return new ObjectMapper().writeValueAsString(results);
356 private Path getAbsolutePath(final String path) {
357 final File file = new File(path);
358 return file.toPath();
361 private byte[] getFileContent(final Path path) throws IOException {
362 return Files.readAllBytes(path);