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);