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=========================================================
20 package org.onap.so.etsi.nfvo.ns.workflow.engine.tasks;
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.put;
26 import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
27 import static org.junit.Assert.assertEquals;
28 import static org.junit.Assert.assertFalse;
29 import static org.junit.Assert.assertNotNull;
30 import static org.junit.Assert.assertNull;
31 import static org.junit.Assert.assertTrue;
32 import static org.junit.Assert.fail;
33 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogServiceProviderConfiguration.ETSI_CATALOG_REST_TEMPLATE_BEAN;
34 import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
35 import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
36 import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
37 import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
38 import java.time.LocalDateTime;
39 import java.util.Arrays;
40 import java.util.HashMap;
42 import java.util.Optional;
43 import java.util.UUID;
44 import org.camunda.bpm.engine.history.HistoricProcessInstance;
45 import org.camunda.bpm.engine.history.HistoricVariableInstance;
46 import org.camunda.bpm.engine.runtime.ProcessInstance;
47 import org.junit.After;
48 import org.junit.Before;
49 import org.junit.Test;
50 import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo;
51 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.BaseTest;
52 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants;
53 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider;
54 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.NsRequestProcessingException;
55 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service.JobExecutorService;
56 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service.WorkflowQueryService;
57 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum;
58 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob;
59 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
60 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
61 import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest;
62 import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
63 import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance;
64 import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance.NsStateEnum;
65 import org.springframework.beans.factory.annotation.Autowired;
66 import org.springframework.beans.factory.annotation.Qualifier;
67 import org.springframework.http.HttpMethod;
68 import org.springframework.http.HttpStatus;
69 import org.springframework.http.MediaType;
70 import org.springframework.http.converter.json.GsonHttpMessageConverter;
71 import org.springframework.test.web.client.MockRestServiceServer;
72 import org.springframework.web.client.RestTemplate;
73 import com.github.tomakehurst.wiremock.client.WireMock;
74 import com.google.gson.Gson;
77 * @author Waqas Ikram (waqas.ikram@est.tech)
80 public class CreateNsTaskTest extends BaseTest {
81 private static final String NSD_ID = UUID.randomUUID().toString();
82 private static final String NS_NAME = "CreateNetworkService-" + NSD_ID;
83 private static final String CREATE_NS_WORKFLOW_NAME = "CreateNs";
86 @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN)
87 private RestTemplate restTemplate;
90 private GsonProvider gsonProvider;
93 private JobExecutorService objUnderTest;
96 private WorkflowQueryService workflowQueryService;
98 private MockRestServiceServer mockRestServiceServer;
103 public void before() {
104 wireMockServer.resetAll();
105 final MockRestServiceServer.MockRestServiceServerBuilder builder = MockRestServiceServer.bindTo(restTemplate);
106 builder.ignoreExpectOrder(true);
107 mockRestServiceServer = builder.build();
108 gson = gsonProvider.getGson();
109 restTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson));
113 public void after() {
114 wireMockServer.resetAll();
115 mockRestServiceServer.reset();
119 public void testCreateNsWorkflow_SuccessfullCase() throws InterruptedException {
120 final CreateNsRequest createNsRequest = getCreateNsRequest();
122 mockEtsiCatalogEndpoints();
123 mockAAIEndpoints(createNsRequest);
125 final NsInstancesNsInstance nsResponse =
126 objUnderTest.runCreateNsJob(createNsRequest, GLOBAL_CUSTOMER_ID, SERVICE_TYPE);
127 assertNotNull(nsResponse);
128 assertNotNull(nsResponse.getId());
130 final Optional<NfvoJob> optional = getJobByResourceId(createNsRequest.getNsdId());
131 assertTrue(optional.isPresent());
132 final NfvoJob nfvoJob = optional.get();
134 assertTrue(waitForProcessInstanceToFinish(nfvoJob.getProcessInstanceId()));
136 mockRestServiceServer.verify();
137 final HistoricProcessInstance historicProcessInstance =
138 getHistoricProcessInstance(nfvoJob.getProcessInstanceId());
139 assertNotNull(historicProcessInstance);
141 assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
142 assertTrue(databaseServiceProvider.isNsInstExists(createNsRequest.getNsName()));
144 final NfvoJob actualJob = optional.get();
145 assertEquals(JobStatusEnum.FINISHED, actualJob.getStatus());
147 assertEquals(NS_NAME, nsResponse.getNsInstanceName());
148 assertEquals(NsStateEnum.NOT_INSTANTIATED, nsResponse.getNsState());
150 final HistoricVariableInstance doesNsPackageExistsVar =
151 getVariable(nfvoJob.getProcessInstanceId(), "doesNsPackageExists");
152 assertNotNull(doesNsPackageExistsVar);
153 assertTrue((boolean) doesNsPackageExistsVar.getValue());
155 final HistoricVariableInstance doesNsInstanceExistsVar =
156 getVariable(nfvoJob.getProcessInstanceId(), "doesNsInstanceExists");
157 assertNotNull(doesNsInstanceExistsVar);
158 assertFalse((boolean) doesNsInstanceExistsVar.getValue());
163 public void testCreateNsWorkflow_FailsToGetNsPackage() throws InterruptedException {
164 final String nsdId = UUID.randomUUID().toString();
165 final String nsdName = NS_NAME + "-" + System.currentTimeMillis();
166 final CreateNsRequest createNsRequest = getCreateNsRequest(nsdId, nsdName);
168 mockRestServiceServer.expect(requestTo(ETSI_CATALOG_URL + "/nsd/v1/ns_descriptors/" + nsdId))
169 .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.NOT_FOUND));
172 objUnderTest.runCreateNsJob(createNsRequest, GLOBAL_CUSTOMER_ID, SERVICE_TYPE);
173 fail("runCreateNsJob should throw exception");
174 } catch (final Exception exception) {
175 assertEquals(NsRequestProcessingException.class, exception.getClass());
178 final Optional<NfvoJob> optional = getJobByResourceId(createNsRequest.getNsdId());
179 assertTrue(optional.isPresent());
180 final NfvoJob nfvoJob = optional.get();
181 assertEquals(JobStatusEnum.ERROR, nfvoJob.getStatus());
183 assertTrue(waitForProcessInstanceToFinish(nfvoJob.getProcessInstanceId()));
185 mockRestServiceServer.verify();
186 final HistoricProcessInstance historicProcessInstance =
187 getHistoricProcessInstance(nfvoJob.getProcessInstanceId());
188 assertNotNull(historicProcessInstance);
190 assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
193 final HistoricVariableInstance nsResponseVariable =
194 getVariable(nfvoJob.getProcessInstanceId(), CamundaVariableNameConstants.CREATE_NS_RESPONSE_PARAM_NAME);
195 assertNull(nsResponseVariable);
197 final Optional<InlineResponse400> problemDetailsOptional =
198 workflowQueryService.getProblemDetails(nfvoJob.getProcessInstanceId());
199 assertTrue(problemDetailsOptional.isPresent());
201 final InlineResponse400 problemDetails = problemDetailsOptional.get();
202 assertNotNull(problemDetails);
203 assertNotNull(problemDetails.getDetail());
205 final HistoricVariableInstance doesNsPackageExistsVar =
206 getVariable(nfvoJob.getProcessInstanceId(), "doesNsPackageExists");
207 assertNotNull(doesNsPackageExistsVar);
208 assertFalse((boolean) doesNsPackageExistsVar.getValue());
209 assertEquals("Unexpected exception occured while getting ns package using nsdId: " + nsdId,
210 problemDetails.getDetail());
214 public void testCreateNsWorkflow_FailsToFindJobUsingJobId() throws InterruptedException {
215 final String nsdId = UUID.randomUUID().toString();
216 final String nsdName = NS_NAME + "-" + System.currentTimeMillis();
217 final CreateNsRequest createNsRequest = getCreateNsRequest(nsdId, nsdName);
219 final String randomJobId = UUID.randomUUID().toString();
220 final ProcessInstance processInstance =
221 executeWorkflow(CREATE_NS_WORKFLOW_NAME, randomJobId, getVariables(randomJobId, createNsRequest));
222 assertTrue(waitForProcessInstanceToFinish(processInstance.getProcessInstanceId()));
224 mockRestServiceServer.verify();
225 final HistoricProcessInstance historicProcessInstance =
226 getHistoricProcessInstance(processInstance.getProcessInstanceId());
227 assertNotNull(historicProcessInstance);
229 assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
231 final HistoricVariableInstance nsResponseVariable = getVariable(processInstance.getProcessInstanceId(),
232 CamundaVariableNameConstants.CREATE_NS_RESPONSE_PARAM_NAME);
234 assertNull(nsResponseVariable);
236 final HistoricVariableInstance workflowExceptionVariable = getVariable(processInstance.getProcessInstanceId(),
237 CamundaVariableNameConstants.NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME);
239 final InlineResponse400 problemDetails = (InlineResponse400) workflowExceptionVariable.getValue();
240 assertNotNull(problemDetails);
241 assertNotNull(problemDetails.getDetail());
242 assertEquals("Unable to find job using job id: " + randomJobId, problemDetails.getDetail());
247 public void testCreateNsWorkflow_NsInstanceExistsInDb() throws InterruptedException {
248 final String nsdId = UUID.randomUUID().toString();
249 final String nsdName = NS_NAME + "-" + System.currentTimeMillis();
250 final CreateNsRequest createNsRequest = getCreateNsRequest(nsdId, nsdName);
252 databaseServiceProvider.saveNfvoNsInst(new NfvoNsInst().nsInstId(nsdId).name(createNsRequest.getNsName())
253 .nsPackageId(UUID.randomUUID().toString()).nsdId(nsdId).nsdInvariantId(nsdId)
254 .description(createNsRequest.getNsDescription()).status(State.INSTANTIATED)
255 .statusUpdatedTime(LocalDateTime.now()).globalCustomerId(GLOBAL_CUSTOMER_ID).serviceType(SERVICE_TYPE));
257 mockEtsiCatalogEndpoints(nsdId);
260 objUnderTest.runCreateNsJob(createNsRequest, GLOBAL_CUSTOMER_ID, SERVICE_TYPE);
261 fail("runCreateNsJob should throw exception");
262 } catch (final Exception exception) {
263 assertEquals(NsRequestProcessingException.class, exception.getClass());
266 final Optional<NfvoJob> optional = getJobByResourceId(createNsRequest.getNsdId());
267 assertTrue(optional.isPresent());
268 final NfvoJob nfvoJob = optional.get();
269 assertEquals(JobStatusEnum.ERROR, nfvoJob.getStatus());
271 assertTrue(waitForProcessInstanceToFinish(nfvoJob.getProcessInstanceId()));
273 mockRestServiceServer.verify();
274 final HistoricProcessInstance historicProcessInstance =
275 getHistoricProcessInstance(nfvoJob.getProcessInstanceId());
276 assertNotNull(historicProcessInstance);
278 assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
279 assertTrue(databaseServiceProvider.isNsInstExists(createNsRequest.getNsName()));
281 final HistoricVariableInstance historicVariableInstance =
282 getVariable(nfvoJob.getProcessInstanceId(), CamundaVariableNameConstants.CREATE_NS_RESPONSE_PARAM_NAME);
284 assertNull(historicVariableInstance);
286 final Optional<InlineResponse400> problemDetailsOptional =
287 workflowQueryService.getProblemDetails(nfvoJob.getProcessInstanceId());
289 final InlineResponse400 problemDetails = problemDetailsOptional.get();
290 assertNotNull(problemDetails);
291 assertNotNull(problemDetails.getDetail());
292 assertTrue(problemDetails.getDetail().startsWith("Ns Instance already exists in database"));
294 final HistoricVariableInstance doesNsInstanceExistsVar =
295 getVariable(nfvoJob.getProcessInstanceId(), "doesNsInstanceExists");
296 assertNotNull(doesNsInstanceExistsVar);
297 assertTrue((boolean) doesNsInstanceExistsVar.getValue());
302 public void testCreateNsWorkflow_FailToCreateResouceInAai() throws InterruptedException {
303 final String nsdId = UUID.randomUUID().toString();
304 final String nsdName = NS_NAME + "-" + System.currentTimeMillis();
305 final CreateNsRequest createNsRequest = getCreateNsRequest(nsdId, nsdName);
307 mockEtsiCatalogEndpoints(nsdId);
309 final String modelEndpoint = getAaiServiceInstanceEndPoint();
310 wireMockServer.stubFor(put(urlMatching(modelEndpoint)).willReturn(WireMock.serverError()));
311 wireMockServer.stubFor(get(urlMatching(modelEndpoint)).willReturn(WireMock.serverError()));
314 objUnderTest.runCreateNsJob(createNsRequest, GLOBAL_CUSTOMER_ID, SERVICE_TYPE);
315 fail("runCreateNsJob should throw exception");
316 } catch (final Exception exception) {
317 assertEquals(NsRequestProcessingException.class, exception.getClass());
319 final Optional<NfvoJob> optional = getJobByResourceId(createNsRequest.getNsdId());
320 assertTrue(optional.isPresent());
321 final NfvoJob nfvoJob = optional.get();
322 assertEquals(JobStatusEnum.ERROR, nfvoJob.getStatus());
324 mockRestServiceServer.verify();
325 final HistoricProcessInstance historicProcessInstance =
326 getHistoricProcessInstance(nfvoJob.getProcessInstanceId());
327 assertNotNull(historicProcessInstance);
329 assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
330 assertTrue(databaseServiceProvider.isNsInstExists(createNsRequest.getNsName()));
332 final Optional<InlineResponse400> problemDetailsOptional =
333 workflowQueryService.getProblemDetails(nfvoJob.getProcessInstanceId());
335 final InlineResponse400 problemDetails = problemDetailsOptional.get();
336 assertNotNull(problemDetails);
337 assertEquals("Unable to Create Service Instance in AAI", problemDetails.getDetail());
341 private void mockAAIEndpoints(final CreateNsRequest createNsRequest) {
342 final String modelEndpoint = getAaiServiceInstanceEndPoint();
344 wireMockServer.stubFor(put(urlMatching(modelEndpoint)).willReturn(ok()));
345 wireMockServer.stubFor(get(urlMatching(modelEndpoint)).willReturn(notFound()));
348 private void mockEtsiCatalogEndpoints(final String nsdId) {
349 mockRestServiceServer.expect(requestTo(ETSI_CATALOG_URL + "/nsd/v1/ns_descriptors/" + nsdId))
350 .andExpect(method(HttpMethod.GET))
351 .andRespond(withSuccess(gson.toJson(getNSPackageModel(NSD_ID)), MediaType.APPLICATION_JSON));
354 private void mockEtsiCatalogEndpoints() {
355 mockEtsiCatalogEndpoints(NSD_ID);;
358 private NsdInfo getNSPackageModel(final String nsdId) {
359 return new NsdInfo().id(nsdId).nsdId(nsdId).nsdInvariantId(NSD_INVARIANT_ID).nsdName("vcpe").nsdDesigner("ONAP")
360 .vnfPkgIds(Arrays.asList(GLOBAL_CUSTOMER_ID));
363 private CreateNsRequest getCreateNsRequest() {
364 return getCreateNsRequest(NSD_ID, NS_NAME);
367 private CreateNsRequest getCreateNsRequest(final String nsdId, final String nsName) {
368 return new CreateNsRequest().nsdId(nsdId).nsName(nsName);
371 private Map<String, Object> getVariables(final String jobId, final CreateNsRequest createNsRequest) {
372 final Map<String, Object> variables = new HashMap<>();
373 variables.put(CamundaVariableNameConstants.JOB_ID_PARAM_NAME, jobId);
374 variables.put(CamundaVariableNameConstants.CREATE_NS_REQUEST_PARAM_NAME, createNsRequest);
375 variables.put(CamundaVariableNameConstants.GLOBAL_CUSTOMER_ID_PARAM_NAME, GLOBAL_CUSTOMER_ID);
376 variables.put(CamundaVariableNameConstants.SERVICE_TYPE_PARAM_NAME, SERVICE_TYPE);