Merge "Enrich Deallocate and Modify Core NSSI sub-processes"
authorByung-Woo Jun <byung-woo.jun@est.tech>
Tue, 29 Sep 2020 16:07:40 +0000 (16:07 +0000)
committerGerrit Code Review <gerrit@onap.org>
Tue, 29 Sep 2020 16:07:40 +0000 (16:07 +0000)
68 files changed:
adapters/etsi-sol002-adapter/src/main/resources/certs/org.onap.so.trust.jks
adapters/etsi-sol002-adapter/src/main/resources/certs/ve-vnfm-adapter.p12
adapters/etsi-sol003-adapter/etsi-sol003-adapter-application/src/main/resources/org.onap.so.trust.jks
adapters/etsi-sol003-adapter/etsi-sol003-adapter-application/src/main/resources/so-vnfm-adapter.p12
bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/OofUtils.groovy
bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/BBInputSetupUtils.java
bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/cds/AbstractCDSProcessingBBUtils.java
bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/cds/ConfigureInstanceParamsForPnf.java [new file with mode: 0644]
bpmn/MSOCommonBPMN/src/test/java/org/onap/so/bpmn/servicedecomposition/tasks/BBInputSetupUtilsTest.java
bpmn/MSOCommonBPMN/src/test/resources/__files/ExecuteBuildingBlock/FlowsToExecute.json
bpmn/MSOCoreBPMN/src/main/java/org/onap/so/bpmn/core/domain/ServiceDecomposition.java
bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CnfAdapterBB.bpmn
bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateCommunicationService.groovy
bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateSliceService.groovy
bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DoAllocateNSIandNSSI.groovy
bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DoAllocateNSSI.groovy
bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DoCreateSliceServiceInstance.groovy
bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DoCreateSliceServiceOption.groovy
bpmn/so-bpmn-infrastructure-flows/src/main/resources/process/CreateSliceService.bpmn
bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/DoAllocateNSIandNSSI.bpmn
bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/DoAllocateNSSI.bpmn
bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/DoCreateSliceServiceInstance.bpmn
bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/DoCreateSliceServiceOption.bpmn
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/aai/tasks/AAICreateTasks.java
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnf/tasks/CnfAdapter.java
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnf/tasks/CnfAdapterCreateTasks.java
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/flowspecific/tasks/GenericPnfCDSControllerRunnableBB.java
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/cnf/CnfAdapterClient.java
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/cnf/entities/InstanceRequest.java
bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/aai/tasks/AAICreateTasksTest.java
bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/flowspecific/tasks/GenericPnfCDSControllerRunnableBBTest.java
common/src/main/java/org/onap/so/beans/nsmf/AnSliceProfile.java
common/src/main/java/org/onap/so/beans/nsmf/SliceTaskParams.java
common/src/main/java/org/onap/so/beans/nsmf/SliceTaskParamsAdapter.java
common/src/main/java/org/onap/so/beans/nsmf/oof/NssiReqBody.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/CamundaVariableNameConstants.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/Constants.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProvider.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/aai/AaiServiceProviderImpl.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProvider.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterServiceProviderImpl.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/extclients/vnfm/Sol003AdapterUrlProvider.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/service/JobExecutorService.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/AbstractNetworkServiceTask.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/CreateInstantiateVnfTask.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/InstantiateNsTask.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterNodeTask.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterTerminateJobTask.java [new file with mode: 0644]
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterTerminateNodeTask.java [new file with mode: 0644]
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/TerminateNsTask.java [new file with mode: 0644]
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/TerminateVnfTask.java [new file with mode: 0644]
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterTerminateJob.bpmn [new file with mode: 0644]
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterTerminateNodeStatus.bpmn [new file with mode: 0644]
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/TerminateNs.bpmn [new file with mode: 0644]
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/TerminateVnf.bpmn [new file with mode: 0644]
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/MonitorSol003AdapterTerminateJobTaskTest.java [new file with mode: 0644]
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/TerminateNsTaskTest.java [new file with mode: 0644]
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/NsLcmOpOcc.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/beans/State.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/NfvoJobRepository.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/RefreshableRepository.java [new file with mode: 0644]
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/RefreshableRepositoryImpl.java [new file with mode: 0644]
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/service/DatabaseServiceProvider.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/database/DatabaseServiceProviderTest.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/EtsiSoNsLcmManagerUrlProvider.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/lifecycle/NsLifeCycleManager.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementController.java
so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-service/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/rest/NsLifecycleManagementControllerTest.java

index 1f0d8a5..4605a24 100644 (file)
Binary files a/adapters/etsi-sol002-adapter/src/main/resources/certs/org.onap.so.trust.jks and b/adapters/etsi-sol002-adapter/src/main/resources/certs/org.onap.so.trust.jks differ
index ae4fddc..d333e57 100644 (file)
Binary files a/adapters/etsi-sol002-adapter/src/main/resources/certs/ve-vnfm-adapter.p12 and b/adapters/etsi-sol002-adapter/src/main/resources/certs/ve-vnfm-adapter.p12 differ
index 1f0d8a5..4605a24 100644 (file)
Binary files a/adapters/etsi-sol003-adapter/etsi-sol003-adapter-application/src/main/resources/org.onap.so.trust.jks and b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-application/src/main/resources/org.onap.so.trust.jks differ
index ae4fddc..6bd786d 100644 (file)
Binary files a/adapters/etsi-sol003-adapter/etsi-sol003-adapter-application/src/main/resources/so-vnfm-adapter.p12 and b/adapters/etsi-sol003-adapter/etsi-sol003-adapter-application/src/main/resources/so-vnfm-adapter.p12 differ
index 44188b4..30cbeaf 100644 (file)
@@ -23,6 +23,7 @@
 package org.onap.so.bpmn.common.scripts
 
 import org.onap.so.beans.nsmf.oof.NsiReqBody
+import org.onap.so.beans.nsmf.oof.NssiReqBody
 import org.onap.so.beans.nsmf.oof.RequestInfo
 import org.onap.so.beans.nsmf.oof.SubnetCapability
 import org.onap.so.beans.nsmf.oof.TemplateInfo
@@ -658,9 +659,10 @@ return json.toString()
 
     public String buildSelectNSIRequest(String requestId, TemplateInfo nstInfo, List<TemplateInfo> nsstInfo,
                                         String messageType, Map<String, Object> serviceProfile,
-                                        List<SubnetCapability> subnetCapabilities, Integer timeOut){
+                                        List<SubnetCapability> subnetCapabilities, Integer timeOut, boolean preferReuse){
 
         def transactionId = requestId
+        String correlator = requestId
         logger.debug( "transactionId is: " + transactionId)
 
         String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
@@ -680,10 +682,39 @@ return json.toString()
         nsiReqBody.setServiceProfile(serviceProfile)
         nsiReqBody.setSubnetCapabilities(subnetCapabilities)
         nsiReqBody.setNSSTInfo(nsstInfo)
-
+        nsiReqBody.setPreferReuse(preferReuse)
 
         ObjectMapper objectMapper = new ObjectMapper()
 
         return objectMapper.writeValueAsString(nsiReqBody)
     }
+
+    public <T> String buildSelectNSSIRequest(String requestId, TemplateInfo nsstInfo, String messageType,
+                                             T sliceProfile, Integer timeOut){
+
+        def transactionId = requestId
+        String correlator = requestId
+        logger.debug( "transactionId is: " + transactionId)
+
+        String callbackUrl = UrnPropertiesReader.getVariable("mso.adapters.oof.callback.endpoint") + "/" + messageType + "/" + correlator
+
+        NssiReqBody nssiReqBody = new NssiReqBody()
+
+        RequestInfo requestInfo = new RequestInfo()
+        requestInfo.setRequestId(requestId)
+        requestInfo.setTransactionId(transactionId)
+        requestInfo.setCallbackUrl(callbackUrl)
+        requestInfo.setSourceId("so")
+        requestInfo.setTimeout(timeOut)
+        //requestInfo.setNumSolutions()
+
+        nssiReqBody.setRequestInfo(requestInfo)
+        nssiReqBody.setSliceProfile(sliceProfile)
+        nssiReqBody.setNSSTInfo(nsstInfo)
+
+
+        ObjectMapper objectMapper = new ObjectMapper()
+
+        return objectMapper.writeValueAsString(nssiReqBody)
+    }
 }
index 9205cae..afd7f64 100644 (file)
@@ -87,7 +87,6 @@ import com.fasterxml.jackson.databind.type.TypeFactory;
 public class BBInputSetupUtils {
 
     private static final Logger logger = LoggerFactory.getLogger(BBInputSetupUtils.class);
-    private ObjectMapper objectMapper = new ObjectMapper();
     private static final String REQUEST_ERROR = "Could not find request.";
     private static final String DATA_LOAD_ERROR = "Could not process loading data from database";
     private static final String DATA_PARSE_ERROR = "Could not parse data";
@@ -190,7 +189,8 @@ public class BBInputSetupUtils {
                                 request.getOriginalRequestId(), PROCESSING_DATA_NAME_EXECUTION_FLOWS);
                 try {
                     ObjectMapper om = new ObjectMapper();
-                    TypeFactory typeFactory = objectMapper.getTypeFactory();
+                    TypeFactory typeFactory = om.getTypeFactory();
+                    om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                     return om.readValue(requestProcessingData.getValue(),
                             typeFactory.constructCollectionType(List.class, ExecuteBuildingBlock.class));
                 } catch (Exception e) {
@@ -246,6 +246,8 @@ public class BBInputSetupUtils {
         if (requestId != null && !requestId.isEmpty()) {
             InfraActiveRequests activeRequest = this.getInfraActiveRequest(requestId);
             String requestBody = activeRequest.getRequestBody().replaceAll("\\\\", "");
+            ObjectMapper objectMapper = new ObjectMapper();
+            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
             objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
             objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
             return objectMapper.readValue(requestBody, RequestDetails.class);
index 51b1a21..55d7681 100644 (file)
@@ -101,6 +101,7 @@ public class AbstractCDSProcessingBBUtils {
             ExecutionServiceInput executionServiceInput = prepareExecutionServiceInput(executionObject);
 
             execution.setVariable(EXEC_INPUT, executionServiceInput);
+            logger.debug("Input payload: " + executionServiceInput.getPayload());
 
         } catch (Exception ex) {
             exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/cds/ConfigureInstanceParamsForPnf.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/cds/ConfigureInstanceParamsForPnf.java
new file mode 100644 (file)
index 0000000..0d79dbb
--- /dev/null
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Nokia
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.client.cds;
+
+import com.google.gson.JsonObject;
+import org.onap.so.client.exception.PayloadGenerationException;
+import org.onap.so.serviceinstancebeans.Service;
+import org.onap.so.serviceinstancebeans.Pnfs;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+@Component
+public class ConfigureInstanceParamsForPnf {
+
+    private ExtractServiceFromUserParameters extractServiceFromUserParameters;
+
+    @Autowired
+    public ConfigureInstanceParamsForPnf(ExtractServiceFromUserParameters extractServiceFromUserParameters) {
+        this.extractServiceFromUserParameters = extractServiceFromUserParameters;
+    }
+
+    /**
+     * Read instance parameters for PNF and put into JsonObject.
+     *
+     * @param jsonObject - JsonObject which will hold the payload to send to CDS.
+     * @param userParamsFromRequest - User parameters.
+     * @param modelCustomizationUuid - Unique ID for Pnf.
+     * @throws PayloadGenerationException if it doesn't able to populate instance parameters from SO payload.
+     */
+    public void populateInstanceParams(JsonObject jsonObject, List<Map<String, Object>> userParamsFromRequest,
+            String modelCustomizationUuid) throws PayloadGenerationException {
+        try {
+            Service service = extractServiceFromUserParameters.getServiceFromRequestUserParams(userParamsFromRequest);
+            List<Map<String, String>> instanceParamsList = getInstanceParamForPnf(service, modelCustomizationUuid);
+
+            instanceParamsList.stream().flatMap(instanceParamsMap -> instanceParamsMap.entrySet().stream())
+                    .forEachOrdered(entry -> jsonObject.addProperty(entry.getKey(), entry.getValue()));
+        } catch (Exception exception) {
+            throw new PayloadGenerationException("Couldn't able to resolve instance parameters", exception);
+        }
+    }
+
+    private List<Map<String, String>> getInstanceParamForPnf(Service service, String genericPnfModelCustomizationUuid)
+            throws PayloadGenerationException {
+        Optional<Pnfs> foundedPnfs = service.getResources().getPnfs().stream()
+                .filter(pnfs -> pnfs.getModelInfo().getModelCustomizationId().equals(genericPnfModelCustomizationUuid))
+                .findFirst();
+        if (foundedPnfs.isPresent()) {
+            return foundedPnfs.get().getInstanceParams();
+        } else {
+            throw new PayloadGenerationException(String.format(
+                    "Can not find pnf for genericPnfModelCustomizationUuid: %s", genericPnfModelCustomizationUuid));
+        }
+    }
+}
index c65b36a..85774ec 100644 (file)
@@ -42,6 +42,7 @@ import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Optional;
+import com.fasterxml.jackson.databind.DeserializationFeature;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -115,6 +116,7 @@ public class BBInputSetupUtilsTest {
 
     @Before
     public void setup() {
+        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
         doReturn(MOCK_aaiResourcesClient).when(MOCK_injectionHelper).getAaiClient();
     }
 
index fa271b9..7bbc287 100644 (file)
@@ -58,7 +58,8 @@
       "vnfResourceCustomizationUUID": "a80f05b8-d651-44af-b999-8ed78fb4582f",
       "cvnfcCustomizationUUID": "69cce457-9ffd-4359-962b-0596a1e83ad1",
       "vnfcName": "zauk51bmcmr01mcm001"
-    }
+    },
+    "resume": null
   },
   {
     "buildingBlock": {
index 70c7847..daf9426 100644 (file)
@@ -55,6 +55,8 @@ public class ServiceDecomposition extends JsonWrapper implements Serializable {
     private String serviceType;
     @JsonProperty("serviceRole")
     private String serviceRole;
+    @JsonProperty("serviceCategory")
+    private String serviceCategory;
     private ServiceInstance serviceInstance;
     private Request request;
     private String callbackURN;
@@ -259,8 +261,17 @@ public class ServiceDecomposition extends JsonWrapper implements Serializable {
         this.serviceProxy = serviceProxy;
     }
 
+
     // *****
 
+    public String getServiceCategory() {
+        return serviceCategory;
+    }
+
+    public void setServiceCategory(String serviceCategory) {
+        this.serviceCategory = serviceCategory;
+    }
+
     // *****
     // Access methods
 
index 6cd2c20..1dc371e 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.10.0">
-  <bpmn:process id="Process_1" isExecutable="true">
+  <bpmn:process id="CnfAdapterBB" name="CnfAdapterBB" isExecutable="true">
     <bpmn:startEvent id="StartEvent_1">
       <bpmn:outgoing>SequenceFlow_0xb4elc</bpmn:outgoing>
     </bpmn:startEvent>
index e253855..6784591 100644 (file)
@@ -20,7 +20,7 @@
 
 package org.onap.so.bpmn.infrastructure.scripts
 
-import static org.apache.commons.lang3.StringUtils.isBlank
+import groovy.json.JsonSlurper
 import org.camunda.bpm.engine.delegate.BpmnError
 import org.camunda.bpm.engine.delegate.DelegateExecution
 import org.json.JSONObject
@@ -44,7 +44,8 @@ import org.onap.so.db.request.beans.OperationStatus
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
 import org.springframework.web.util.UriUtils
-import groovy.json.JsonSlurper
+
+import static org.apache.commons.lang3.StringUtils.isBlank
 
 /**
  * This groovy class supports the <class>DoCreateCommunicationService.bpmn</class> process.
@@ -349,7 +350,7 @@ class CreateCommunicationService extends AbstractServiceTaskProcessor {
     /**
      * get E2EST id through CST id and change communication profile to E2E service profile
      * 1. get E2EST id from cst
-     * 1.1 æŸ¥source service id
+     * 1.1 source service id
      * 1.2 source service
      * 1.3 source service input, init e2e profile
      */
@@ -383,9 +384,29 @@ class CreateCommunicationService extends AbstractServiceTaskProcessor {
                 }
             }
 
-            //TODO
+            //TODO temp solution
             e2eInputMap.put("sNSSAI", execution.getVariable("sNSSAI_id"))
                e2eInputMap.put("sST", execution.getVariable("csServiceType"))
+
+            Integer activityFactor = 60
+            Integer random = new Random().nextInt(5) + 2
+            Integer dLThptPerUE = Integer.parseInt(csInputMap.get("expDataRateDL").toString())
+            Integer uLThptPerUE = Integer.parseInt(csInputMap.get("expDataRateUL").toString())
+            Integer maxNumberofUEs = Integer.parseInt(csInputMap.get("maxNumberofUEs").toString())
+            Integer dLThptPerSlice = dLThptPerUE * maxNumberofUEs * activityFactor * random
+            Integer uLThptPerSlice = uLThptPerUE * maxNumberofUEs * activityFactor * random
+            Integer maxNumberofConns = maxNumberofUEs * activityFactor * 3
+
+            e2eInputMap.put("jitter", 10)
+            e2eInputMap.put("activityFactor", activityFactor)
+            e2eInputMap.put("maxNumberofUEs", maxNumberofUEs)
+            e2eInputMap.put("dLThptPerUE", dLThptPerUE)
+            e2eInputMap.put("uLThptPerUE", uLThptPerUE)
+            e2eInputMap.put("dLThptPerSlice", dLThptPerSlice)
+            e2eInputMap.put("uLThptPerSlice", uLThptPerSlice)
+            e2eInputMap.put("maxNumberofConns", maxNumberofConns)
+            e2eInputMap.put("coverageAreaTAList", csInputMap.get("coverageAreaList"))
+
             execution.setVariable("e2eInputMap", e2eInputMap)
             execution.setVariable("e2eServiceType", e2eServiceDecomposition.getServiceType())
             execution.setVariable("e2eModelInvariantUuid", e2eServiceDecomposition.getModelInfo().getModelInvariantUuid())
index 65398eb..72fd052 100644 (file)
@@ -20,6 +20,8 @@
 
 package org.onap.so.bpmn.infrastructure.scripts
 
+import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
+
 import static org.apache.commons.lang3.StringUtils.*
 import org.camunda.bpm.engine.delegate.BpmnError
 import org.camunda.bpm.engine.delegate.DelegateExecution
@@ -52,11 +54,15 @@ public class CreateSliceService extends AbstractServiceTaskProcessor {
     String Prefix = "CRESS_"
 
     ExceptionUtil exceptionUtil = new ExceptionUtil()
+
     JsonUtils jsonUtil = new JsonUtils()
+
     JsonSlurper jsonSlurper = new JsonSlurper()
+
     ObjectMapper objectMapper = new ObjectMapper()
+
     OofUtils oofUtils = new OofUtils()
-    NssmfAdapterUtils nssmfAdapterUtils = new NssmfAdapterUtils(httpClientFactory, jsonUtil)
+
     AAIResourcesClient client = getAAIClient()
 
     private static final Logger logger = LoggerFactory.getLogger(CreateSliceService.class)
@@ -161,8 +167,7 @@ public class CreateSliceService extends AbstractServiceTaskProcessor {
 
             execution.setVariable("serviceInputParams", inputMap)
             execution.setVariable("uuiRequest", uuiRequest)
-            execution.setVariable("se" +
-                    "rviceProfile", serviceProfile)
+            execution.setVariable("serviceProfile", serviceProfile)
 
             //TODO
             //execution.setVariable("serviceInputParams", jsonUtil.getJsonValue(siRequest, "requestDetails.requestParameters.userParams"))
@@ -267,10 +272,8 @@ public class CreateSliceService extends AbstractServiceTaskProcessor {
 
         execution.setVariable("sliceTaskParams", sliceTaskParams)
 
-        //todo:----------------------------------------
-//        String paramJson = sliceTaskParams.convertToJson()
-//        execution.setVariable("CSSOT_paramJson", paramJson)
-        /*-------------------------------------------*/
+        String paramJson = sliceTaskParams.convertToJson()
+        execution.setVariable("CSSOT_paramJson", paramJson)
 
         logger.debug("Finish createOrchestrationTask")
     }
@@ -360,7 +363,8 @@ public class CreateSliceService extends AbstractServiceTaskProcessor {
         logger.debug("Start prepareUpdateOrchestrationTask")
         String requestMethod = "PUT"
         String taskStatus = execution.getVariable("taskStatus")
-        SliceTaskParams sliceTaskParams = execution.getVariable("sliceTaskParams")
+        SliceTaskParamsAdapter sliceTaskParams =
+                execution.getVariable("sliceTaskParams") as SliceTaskParamsAdapter
         String paramJson = sliceTaskParams.convertToJson()
         execution.setVariable("CSSOT_status", taskStatus)
         execution.setVariable("CSSOT_paramJson", paramJson)
@@ -390,7 +394,7 @@ public class CreateSliceService extends AbstractServiceTaskProcessor {
         OrchestrationTask orchestrationTask = objectMapper.readValue(response, OrchestrationTask.class)
         String paramJson = orchestrationTask.getParams()
         logger.debug("paramJson: " + paramJson)
-        SliceTaskParams sliceTaskParams = new SliceTaskParams()
+        SliceTaskParamsAdapter sliceTaskParams = new SliceTaskParamsAdapter()
         sliceTaskParams.convertFromJson(paramJson)
         execution.setVariable("sliceTaskParams", sliceTaskParams)
         logger.debug("Finish processUserOptions")
@@ -404,7 +408,7 @@ public class CreateSliceService extends AbstractServiceTaskProcessor {
         try {
             ServiceInstance si = new ServiceInstance()
             si.setOrchestrationStatus(orchStatus)
-            AAIResourcesClient client = new AAIResourcesClient()
+
             AAIResourceUri uri = AAIUriFactory.createResourceUri(Types.SERVICE_INSTANCE.getFragment(serviceInstanceId))
             client.update(uri, si)
         } catch (BpmnError e) {
index c497fc4..d0c189c 100644 (file)
@@ -20,7 +20,8 @@
 
 package org.onap.so.bpmn.infrastructure.scripts
 
-import static org.apache.commons.lang3.StringUtils.isBlank
+import org.onap.so.beans.nsmf.oof.SubnetType
+import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
 import javax.ws.rs.NotFoundException
 import org.camunda.bpm.engine.delegate.BpmnError
 import org.camunda.bpm.engine.delegate.DelegateExecution
@@ -49,8 +50,9 @@ import org.onap.so.bpmn.common.scripts.ExceptionUtil
 import org.onap.so.bpmn.core.json.JsonUtils
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
+import static org.apache.commons.lang3.StringUtils.isBlank
 
-class DoAllocateNSIandNSSI extends org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor{
+class DoAllocateNSIandNSSI extends AbstractServiceTaskProcessor{
 
     private static final Logger logger = LoggerFactory.getLogger(DoAllocateNSIandNSSI.class);
 
@@ -338,6 +340,7 @@ class DoAllocateNSIandNSSI extends org.onap.so.bpmn.common.scripts.AbstractServi
 
         execution.setVariable("AnAllocateNssiNbiRequest", nbiRequest)
         execution.setVariable("anBHSliceTaskInfo", sliceTaskInfo)
+        execution.setVariable("anSubnetType", SubnetType.AN_NF)
     }
 
 
@@ -384,7 +387,7 @@ class DoAllocateNSIandNSSI extends org.onap.so.bpmn.common.scripts.AbstractServi
     }
 
     /**
-     * create An Slice Profile
+     * create Cn Slice Profile
      * @param execution
      */
     void createCnSliceProfile(DelegateExecution execution) {
@@ -426,7 +429,7 @@ class DoAllocateNSIandNSSI extends org.onap.so.bpmn.common.scripts.AbstractServi
 
         AllocateCnNssi allocateCnNssi = new AllocateCnNssi()
         allocateCnNssi.nsstId = sliceTaskInfo.NSSTInfo.UUID
-        allocateCnNssi.nssiId = sliceTaskInfo.NSSTInfo.UUID
+        allocateCnNssi.nssiId = sliceTaskInfo.suggestNssiId
         allocateCnNssi.nssiName = sliceTaskInfo.NSSTInfo.name
         allocateCnNssi.sliceProfile = sliceTaskInfo.sliceProfile
         allocateCnNssi.nsiInfo.nsiId = sliceParams.suggestNsiId
@@ -446,6 +449,7 @@ class DoAllocateNSIandNSSI extends org.onap.so.bpmn.common.scripts.AbstractServi
         serviceInfo.nsiId = sliceParams.suggestNsiId
         serviceInfo.serviceInvariantUuid = sliceTaskInfo.NSSTInfo.invariantUUID
         serviceInfo.serviceUuid = sliceTaskInfo.NSSTInfo.UUID
+        serviceInfo.nssiId = sliceTaskInfo.suggestNssiId //if shared
 
         nbiRequest.setServiceInfo(serviceInfo)
         nbiRequest.setEsrInfo(esrInfo)
@@ -453,6 +457,7 @@ class DoAllocateNSIandNSSI extends org.onap.so.bpmn.common.scripts.AbstractServi
 
         execution.setVariable("CnAllocateNssiNbiRequest", nbiRequest)
         execution.setVariable("cnSliceTaskInfo", sliceTaskInfo)
+        execution.setVariable("cnSubnetType", SubnetType.CN)
     }
 
 
@@ -501,7 +506,7 @@ class DoAllocateNSIandNSSI extends org.onap.so.bpmn.common.scripts.AbstractServi
     }
 
     /**
-     * create An Slice Profile
+     * create Tn Slice Profile
      * @param execution
      */
     void createTnBHSliceProfile(DelegateExecution execution) {
@@ -542,6 +547,7 @@ class DoAllocateNSIandNSSI extends org.onap.so.bpmn.common.scripts.AbstractServi
 
         AllocateTnNssi allocateTnNssi = new AllocateTnNssi()
         //todo: AllocateTnNssi
+        //todo: endpointId -> set into tn
         allocateTnNssi.setTransportSliceNetworks()
         allocateTnNssi.setNetworkSliceInfos()
 
@@ -561,6 +567,7 @@ class DoAllocateNSIandNSSI extends org.onap.so.bpmn.common.scripts.AbstractServi
         serviceInfo.nsiId = sliceParams.suggestNsiId
         serviceInfo.serviceInvariantUuid = sliceTaskInfo.NSSTInfo.invariantUUID
         serviceInfo.serviceUuid = sliceTaskInfo.NSSTInfo.UUID
+        serviceInfo.nssiId = sliceTaskInfo.suggestNssiId
 
         nbiRequest.setServiceInfo(serviceInfo)
         nbiRequest.setEsrInfo(esrInfo)
@@ -568,6 +575,7 @@ class DoAllocateNSIandNSSI extends org.onap.so.bpmn.common.scripts.AbstractServi
 
         execution.setVariable("TnBHAllocateNssiNbiRequest", nbiRequest)
         execution.setVariable("tnBHSliceTaskInfo", sliceTaskInfo)
+        execution.setVariable("tnBHSubnetType", SubnetType.TN_BH)
     }
 
     /**
@@ -586,11 +594,13 @@ class DoAllocateNSIandNSSI extends org.onap.so.bpmn.common.scripts.AbstractServi
 
         ResponseDescriptor result = execution.getVariable("anNssiAllocateResult") as ResponseDescriptor
         String nssiId = result.getNssiId()
-        String endPointId = result.getEndPointId()
         String nsiId = sliceParams.getSuggestNsiId()
         String sliceProfileInstanceId = sliceParams.anSliceTaskInfo.sliceInstanceId
         String serviceProfileInstanceId = sliceParams.serviceId
         //nsi id
+        //todo: aai -> nssi -> relationship -> endpointId -> set into tn
+        String endPointId = getEndpointIdFromAAI(execution, nssiId)
+        execution.setVariable("endPointIdAn", endPointId)
 
         updateRelationship(execution, nsiId, nssiId)
 
@@ -598,8 +608,8 @@ class DoAllocateNSIandNSSI extends org.onap.so.bpmn.common.scripts.AbstractServi
 
         updateRelationship(execution, sliceProfileInstanceId, nssiId)
 
-        updateRelationship(execution, sliceProfileInstanceId, endPointId)
-
+        sliceParams.anSliceTaskInfo.suggestNssiId = nssiId
+        execution.setVariable("sliceTaskParams", sliceParams)
     }
 
 
@@ -622,6 +632,9 @@ class DoAllocateNSIandNSSI extends org.onap.so.bpmn.common.scripts.AbstractServi
         String sliceProfileInstanceId = sliceParams.cnSliceTaskInfo.sliceInstanceId
         String serviceProfileInstanceId = sliceParams.serviceId
         //nsi id
+        //todo: aai -> nssi -> relationship -> endpointId -> set into tn
+        String endPointId = getEndpointIdFromAAI(execution, nssiId)
+        execution.setVariable("endPointIdCn", endPointId)
 
         updateRelationship(execution, nsiId, nssiId)
 
@@ -629,7 +642,58 @@ class DoAllocateNSIandNSSI extends org.onap.so.bpmn.common.scripts.AbstractServi
 
         updateRelationship(execution,sliceProfileInstanceId, nssiId)
 
+        sliceParams.cnSliceTaskInfo.suggestNssiId = nssiId
+        execution.setVariable("sliceTaskParams", sliceParams)
+    }
 
+    /**
+     * get endpoint Id from AAI by nssi id
+     * @param execution
+     * @param nssiId
+     * @return
+     */
+    private String getEndpointIdFromAAI(DelegateExecution execution, String nssiId) {
+        logger.debug("Enter update relationship in DoAllocateNSIandNSSI()")
+        //todo: allottedResourceId
+
+        SliceTaskParamsAdapter sliceParams =
+                execution.getVariable("sliceTaskParams") as SliceTaskParamsAdapter
+
+        //sliceParams.setServiceId(nsiServiceInstanceID)
+        AAIResourceUri nsiServiceUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business().customer(globalSubscriberId).serviceSubscription(subscriptionServiceType).serviceInstance(nssiId))
+
+        String endpointId = null
+
+        try {
+            AAIResultWrapper wrapper = client.get(nsiServiceUri, NotFoundException.class)
+            Optional<ServiceInstance> si = wrapper.asBean(ServiceInstance.class)
+            //todo: if exists
+            if (!si.ifPresent()) {
+                String msg = "NSSI in the option doesn't exist. " + nssiId
+                logger.debug(msg)
+                exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
+            }
+
+            if (si.ifPresent()) {
+                ServiceInstance nssiInstance = si.get()
+                //todo: handle relationship and return endpointId
+                for (Relationship relationship : nssiInstance.relationshipList.getRelationship()) {
+                    if (relationship.relationshipLabel){
+                        endpointId = relationship //todo
+                    }
+                }
+
+                return endpointId
+            }
+
+        }catch(BpmnError e) {
+            throw e
+        }catch (Exception ex){
+            String msg = "NSSI suggested in the option doesn't exist. " + nssiId
+            logger.debug(msg)
+            exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg)
+        }
+        logger.debug("Exit update relationship in DoAllocateNSIandNSSI()")
     }
 
     /**
@@ -656,6 +720,9 @@ class DoAllocateNSIandNSSI extends org.onap.so.bpmn.common.scripts.AbstractServi
         updateRelationship(execution, serviceProfileInstanceId, sliceProfileInstanceId)
 
         updateRelationship(execution,sliceProfileInstanceId, nssiId)
+
+        sliceParams.tnBHSliceTaskInfo.suggestNssiId = nssiId
+        execution.setVariable("sliceTaskParams", sliceParams)
     }
 
     /**
index 35f7257..88014e7 100644 (file)
@@ -1,6 +1,7 @@
 package org.onap.so.bpmn.infrastructure.scripts
 
 import com.fasterxml.jackson.databind.ObjectMapper
+import org.apache.commons.lang3.StringUtils
 import org.camunda.bpm.engine.delegate.DelegateExecution
 import org.onap.so.beans.nsmf.EsrInfo
 import org.onap.so.beans.nsmf.NssiResponse
@@ -8,24 +9,16 @@ import org.onap.so.beans.nsmf.NssmfAdapterNBIRequest
 import org.onap.so.beans.nsmf.ResponseDescriptor
 import org.onap.so.beans.nsmf.ServiceInfo
 import org.onap.so.beans.nsmf.SliceTaskInfo
+import org.onap.so.beans.nsmf.SliceTaskParamsAdapter
+import org.onap.so.beans.nsmf.oof.SubnetType
 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
 import org.onap.so.bpmn.common.scripts.ExceptionUtil
 import org.onap.so.bpmn.common.scripts.NssmfAdapterUtils
-import org.onap.so.bpmn.core.domain.ModelInfo
-import org.onap.so.bpmn.core.domain.ServiceDecomposition
 import org.onap.so.bpmn.core.json.JsonUtils
-import org.onap.aaiclient.client.aai.AAIObjectType
-import org.onap.aaiclient.client.aai.AAIResourcesClient
-import org.onap.aaiclient.client.aai.entities.AAIEdgeLabel
-import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
-import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
-import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
-import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
 import org.springframework.http.ResponseEntity
 
-import static org.apache.commons.lang3.StringUtils.isBlank
 
 class DoAllocateNSSI extends AbstractServiceTaskProcessor {
 
@@ -49,13 +42,15 @@ class DoAllocateNSSI extends AbstractServiceTaskProcessor {
 
         NssmfAdapterNBIRequest nbiRequest = execution.getVariable("nbiRequest") as NssmfAdapterNBIRequest
 
-        //SliceTaskInfo sliceTaskInfo = execution.getVariable("sliceTaskInfo") as SliceTaskInfo
+        execution.setVariable("currentCycle", 0)
         boolean isNSIOptionAvailable = execution.getVariable("isNSIOptionAvailable") as Boolean
 
-        if (isNSIOptionAvailable) {
-            nbiRequest.serviceInfo.setActionType("modify")
-        } else {
+        if (!isNSIOptionAvailable) {
             nbiRequest.serviceInfo.setActionType("allocate")
+        } else if (StringUtils.isBlank(nbiRequest.serviceInfo.nssiId)){
+            nbiRequest.serviceInfo.setActionType("allocate")
+        } else {
+            nbiRequest.serviceInfo.setActionType("modify")
         }
         execution.setVariable("nbiRequest", nbiRequest)
         logger.trace("Exit preProcessRequest")
@@ -111,11 +106,67 @@ class DoAllocateNSSI extends AbstractServiceTaskProcessor {
     }
 
     void prepareUpdateOrchestrationTask(DelegateExecution execution) {
-        //todoï¼›update orchestration task
+        logger.debug("Start prepareUpdateOrchestrationTask progress")
+        String requestMethod = "PUT"
+
+        SliceTaskParamsAdapter sliceParams =
+                execution.getVariable("sliceTaskParams") as SliceTaskParamsAdapter
+        ResponseDescriptor response = execution.getVariable("nssiAllocateResult") as ResponseDescriptor
+        SubnetType subnetType = execution.getVariable("subnetType") as SubnetType
+
+
+        SliceTaskInfo sliceTaskInfo = execution.getVariable("sliceTaskInfo") as SliceTaskInfo
+        sliceTaskInfo.progress = response.getProgress()
+        sliceTaskInfo.status = response.getStatus()
+        sliceTaskInfo.statusDescription = response.getStatusDescription()
+        updateNssiResult(sliceParams, subnetType, sliceTaskInfo)
+
+        String paramJson = sliceParams.convertToJson()
+        execution.setVariable("CSSOT_paramJson", paramJson)
+        execution.setVariable("CSSOT_requestMethod", requestMethod)
+
+        execution.setVariable("sliceTaskParams", sliceParams)
+        execution.setVariable("sliceTaskInfo", sliceTaskInfo)
+        logger.debug("Finish prepareUpdateOrchestrationTask progress")
+    }
+
+    private void updateNssiResult(SliceTaskParamsAdapter sliceTaskParams, SubnetType subnetType,
+                                  SliceTaskInfo sliceTaskInfo) {
+        switch (subnetType) {
+            case SubnetType.CN:
+                sliceTaskParams.cnSliceTaskInfo = sliceTaskInfo
+                break
+            case SubnetType.AN_NF:
+                sliceTaskParams.anSliceTaskInfo = sliceTaskInfo
+                break
+            case SubnetType.TN_BH:
+                sliceTaskParams.tnBHSliceTaskInfo = sliceTaskInfo
+                break
+            case SubnetType.TN_FH:
+                sliceTaskParams.tnFHSliceTaskInfo = sliceTaskInfo
+                break
+            case SubnetType.TN_MH:
+                sliceTaskParams.tnMHSliceTaskInfo = sliceTaskInfo
+                break
+        }
     }
 
     void timeDelay(DelegateExecution execution) {
-        //todo: time delay
+        logger.trace("Enter timeDelay in DoAllocateNSSI()")
+        try {
+            Thread.sleep(60000)
+            int currentCycle = execution.getVariable("currentCycle") as Integer
+            currentCycle = currentCycle + 1
+            if(currentCycle >  60)
+            {
+                logger.trace("Completed all the retry times... but still nssmf havent completed the creation process...")
+                exceptionUtil.buildAndThrowWorkflowException(execution, 500, "NSSMF creation didnt complete by time...")
+            }
+            execution.setVariable("currentCycle", currentCycle)
+        } catch(InterruptedException e) {
+            logger.info("Time Delay exception" + e)
+        }
+        logger.trace("Exit timeDelay in DoAllocateNSSI()")
     }
 
 }
index f64f5e8..48e1acd 100644 (file)
@@ -132,7 +132,7 @@ class DoCreateSliceServiceInstance extends AbstractServiceTaskProcessor{
         }
 
 
-        def rollbackData = execution.getVariable("RollbackData")
+        RollbackData rollbackData = execution.getVariable("RollbackData")
         if (rollbackData == null) {
             rollbackData = new RollbackData()
         }
@@ -171,19 +171,15 @@ class DoCreateSliceServiceInstance extends AbstractServiceTaskProcessor{
         serviceProfile.setCoverageAreaTAList(serviceProfileMap.get("coverageAreaTAList").toString())
         serviceProfile.setUeMobilityLevel(serviceProfileMap.get("uEMobilityLevel").toString())
         serviceProfile.setResourceSharingLevel(serviceProfileMap.get("resourceSharingLevel").toString())
-        serviceProfile.setExpDataRateUL(Integer.parseInt(serviceProfileMap.get("expDataRateUL").toString()))
-        serviceProfile.setExpDataRateDL(Integer.parseInt(serviceProfileMap.get("expDataRateDL").toString()))
-        serviceProfile.setAreaTrafficCapUL(Integer.parseInt(serviceProfileMap.get("areaTrafficCapUL").toString()))
-        serviceProfile.setAreaTrafficCapDL(Integer.parseInt(serviceProfileMap.get("areaTrafficCapDL").toString()))
+        serviceProfile.setDlThptPerSlice(Integer.parseInt(serviceProfileMap.get("dLThptPerSlice").toString()))
+        serviceProfile.setDlThptPerUE(Integer.parseInt(serviceProfileMap.get("dLThptPerUE").toString()))
+        serviceProfile.setUlThptPerSlice(Integer.parseInt(serviceProfileMap.get("uLThptPerSlice").toString()))
+        serviceProfile.setUlThptPerUE(Integer.parseInt(serviceProfileMap.get("uLThptPerUE").toString()))
         serviceProfile.setActivityFactor(Integer.parseInt(serviceProfileMap.get("activityFactor").toString()))
 
-        serviceProfile.setJitter(0)
+        serviceProfile.setJitter(Integer.parseInt(serviceProfileMap.get("jitter").toString()))
         serviceProfile.setSurvivalTime("0")
-        serviceProfile.setCsAvailability(new Object())
         serviceProfile.setReliability("")
-        serviceProfile.setExpDataRate(0)
-        serviceProfile.setTrafficDensity(0)
-        serviceProfile.setConnDensity(0)
         try {
             AAIResourceUri uri = AAIUriFactory.createResourceUri(
                 AAIFluentTypeBuilder.business().customer(execution.getVariable("globalSubscriberId"))
index 161b920..8993127 100644 (file)
@@ -27,7 +27,6 @@ import org.onap.so.beans.nsmf.CnSliceProfile
 import org.onap.so.beans.nsmf.EsrInfo
 import org.onap.so.beans.nsmf.NetworkType
 import org.onap.so.beans.nsmf.NssmfAdapterNBIRequest
-import org.onap.so.beans.nsmf.SliceTaskParams
 import org.onap.so.beans.nsmf.SliceTaskParamsAdapter
 import org.onap.so.beans.nsmf.TnSliceProfile
 import org.onap.so.beans.nsmf.oof.SubnetCapability
@@ -42,15 +41,6 @@ import org.onap.so.bpmn.core.domain.AllottedResource
 import org.onap.so.bpmn.core.domain.ModelInfo
 import org.onap.so.bpmn.core.domain.ServiceDecomposition
 import org.onap.so.bpmn.core.json.JsonUtils
-import org.onap.so.client.HttpClient
-import org.onap.so.client.HttpClientFactory
-import org.onap.aaiclient.client.aai.AAIObjectType
-import org.onap.aaiclient.client.aai.AAIResourcesClient
-import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
-import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
-import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
-import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
-import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
 import org.springframework.http.ResponseEntity
@@ -181,7 +171,6 @@ class DoCreateSliceServiceOption extends AbstractServiceTaskProcessor{
      * @param execution
      */
     public void handleNsstByType(DelegateExecution execution) {
-        //todo: set to sliceTaskParams by type
 
         SliceTaskParamsAdapter sliceParams =
                 execution.getVariable("sliceTaskParams") as SliceTaskParamsAdapter
@@ -194,11 +183,8 @@ class DoCreateSliceServiceOption extends AbstractServiceTaskProcessor{
 
 
         for (ServiceDecomposition serviceDecomposition : nsstServiceDecompositions) {
-            //todo:
             SubnetCapability subnetCapability = new SubnetCapability()
-
             handleByType(execution, serviceDecomposition, sliceParams, subnetCapability)
-
             subnetCapabilities.add(subnetCapability)
         }
 
@@ -208,15 +194,12 @@ class DoCreateSliceServiceOption extends AbstractServiceTaskProcessor{
 
     private void handleByType(DelegateExecution execution, ServiceDecomposition serviceDecomposition,
                               SliceTaskParamsAdapter sliceParams, SubnetCapability subnetCapability) {
-        //todo:
-        String domainType = ""
         ModelInfo modelInfo = serviceDecomposition.getModelInfo()
         String vendor = serviceDecomposition.getServiceRole()
-        SubnetType subnetType
+        SubnetType subnetType = convertServiceCategory(serviceDecomposition.getServiceCategory())
 
-        switch (domainType) {
-            case "tn_bh":
-                subnetType = SubnetType.TN_BH
+        switch (subnetType) {
+            case SubnetType.TN_BH:
                 sliceParams.tnBHSliceTaskInfo.vendor = vendor
                 sliceParams.tnBHSliceTaskInfo.subnetType = subnetType
                 sliceParams.tnBHSliceTaskInfo.networkType = subnetType.networkType
@@ -225,8 +208,7 @@ class DoCreateSliceServiceOption extends AbstractServiceTaskProcessor{
                 sliceParams.tnBHSliceTaskInfo.NSSTInfo.name = modelInfo.getModelName()
 
                 break
-            case "tn_mh":
-                subnetType = SubnetType.TN_MH
+            case SubnetType.TN_MH:
                 sliceParams.tnMHSliceTaskInfo.vendor = vendor
                 sliceParams.tnMHSliceTaskInfo.subnetType = subnetType
                 sliceParams.tnMHSliceTaskInfo.networkType = subnetType.networkType
@@ -235,8 +217,7 @@ class DoCreateSliceServiceOption extends AbstractServiceTaskProcessor{
                 sliceParams.tnMHSliceTaskInfo.NSSTInfo.name = modelInfo.getModelName()
 
                 break
-            case "an_nf":
-                subnetType = SubnetType.AN_NF
+            case SubnetType.AN_NF:
                 sliceParams.anSliceTaskInfo.vendor = vendor
                 sliceParams.anSliceTaskInfo.subnetType = subnetType
                 sliceParams.anSliceTaskInfo.networkType = subnetType.networkType
@@ -244,8 +225,7 @@ class DoCreateSliceServiceOption extends AbstractServiceTaskProcessor{
                 sliceParams.anSliceTaskInfo.NSSTInfo.invariantUUID = modelInfo.getModelInvariantUuid()
                 sliceParams.anSliceTaskInfo.NSSTInfo.name = modelInfo.getModelName()
                 break
-            case "cn":
-                subnetType = SubnetType.CN
+            case SubnetType.CN:
                 sliceParams.cnSliceTaskInfo.vendor = vendor
                 sliceParams.cnSliceTaskInfo.subnetType = subnetType
                 sliceParams.cnSliceTaskInfo.networkType = subnetType.networkType
@@ -260,9 +240,10 @@ class DoCreateSliceServiceOption extends AbstractServiceTaskProcessor{
         //todo
 
         }
-        if (subnetType == null) {
-            //todo: throw error
-            return
+        if (null == subnetType) {
+            def msg = "Get subnetType failed, modelUUId=" + modelInfo.getModelUuid()
+            logger.error(msg)
+            exceptionUtil.buildAndThrowWorkflowException(execution, 500, msg)
         }
         String response = querySubnetCapability(execution, vendor, subnetType)
         ResponseEntity responseEntity = objectMapper.readValue(response, ResponseEntity.class)
@@ -274,6 +255,26 @@ class DoCreateSliceServiceOption extends AbstractServiceTaskProcessor{
         }
     }
 
+    /**
+     * get subnetType from serviceCategory
+     * @return
+     */
+    private SubnetType convertServiceCategory(String serviceCategory){
+        if(serviceCategory ==~ /CN.*/){
+            return SubnetType.CN
+        }
+        if (serviceCategory ==~ /AN.*NF.*/){
+            return SubnetType.AN_NF
+        }
+        if (serviceCategory ==~ /TN.*BH.*/){
+            return SubnetType.TN_BH
+        }
+        if(serviceCategory ==~ /TN.*MH.*/){
+            return SubnetType.TN_MH
+        }
+        return null
+    }
+
     /**
      * query Subnet Capability of TN AN CN
      * @param execution
@@ -319,12 +320,11 @@ class DoCreateSliceServiceOption extends AbstractServiceTaskProcessor{
      * prepare select nsi request
      * @param execution
      */
-    public void preNSIRequest(DelegateExecution execution) {
+    public void preNSIRequest(DelegateExecution execution, boolean preferReuse) {
 
         String urlString = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution)
         logger.debug( "get NSI option OOF Url: " + urlString)
 
-
         String requestId = execution.getVariable("msoRequestId")
         String messageType = "NSISelectionResponse"
 
@@ -346,7 +346,7 @@ class DoCreateSliceServiceOption extends AbstractServiceTaskProcessor{
                 execution.getVariable("subnetCapabilities") as List<SubnetCapability>
 
         String oofRequest = oofUtils.buildSelectNSIRequest(requestId, nstInfo, nsstInfos,
-                messageType, profileInfo, subnetCapabilities, timeout as Integer)
+                messageType, profileInfo, subnetCapabilities, timeout as Integer, preferReuse)
 
         execution.setVariable("nsiSelection_oofRequest", oofRequest)
         logger.debug("Sending request to OOF: " + oofRequest)
@@ -362,12 +362,12 @@ class DoCreateSliceServiceOption extends AbstractServiceTaskProcessor{
         SliceTaskParamsAdapter sliceTaskParams =
                 execution.getVariable("sliceTaskParams") as SliceTaskParamsAdapter
 
-        String OOFResponse = execution.getVariable("nsiSelection_oofResponse")
-        logger.debug("NSI OOFResponse is: " + OOFResponse)
-        execution.setVariable("OOFResponse", OOFResponse)
+        String oofResponse = execution.getVariable("nsiSelection_oofResponse")
+        logger.debug("NSI oofResponse is: " + oofResponse)
+        execution.setVariable("oofResponse", oofResponse)
         //This needs to be changed to derive a value when we add policy to decide the solution options.
 
-        Map<String, Object> resMap = objectMapper.readValue(OOFResponse, Map.class)
+        Map<String, Object> resMap = objectMapper.readValue(oofResponse, Map.class)
         List<Map<String, Object>> nsiSolutions = (List<Map<String, Object>>) resMap.get("solutions")
         Map<String, Object> solution = nsiSolutions.get(0)
 
@@ -511,82 +511,182 @@ class DoCreateSliceServiceOption extends AbstractServiceTaskProcessor{
                 execution.getVariable("sliceTaskParams") as SliceTaskParamsAdapter
 
         //todo
+        boolean needCnNssiSelection = execution.getVariable("NEED_CN_NSSI_SELECTION") as Boolean
+        boolean needAnNssiSelection = execution.getVariable("NEED_AN_NSSI_SELECTION") as Boolean
+        boolean needTnNssiSelection = execution.getVariable("NEED_TN_NSSI_SELECTION") as Boolean
+
+        /**
+         * [
+         * â€‹ {
+         * â€‹         "subType":  subtype,
+         * â€‹         "nsstInfo": object,
+         * â€‹         "sliceProfile": object
+         * â€‹ },
+         *      {
+         *          "subType":  subtype,
+         *          "nsstInfo": object,
+         *          "sliceProfile": object
+         *      }
+         * ]
+         */
+        List<Map> nssiNeedHandlerInfos = new ArrayList<>()
+        Map<String, Object> nssiNeedHandlerMap = new HashMap()
+
+        //List<TemplateInfo> nssiNeedHandlers = new ArrayList<>()
+        //List<Object> nssiProfileNeedHandlers = new ArrayList<>()
+        if (needCnNssiSelection) {
+            nssiNeedHandlerMap.put("subnetType", sliceTaskParams.cnSliceTaskInfo.subnetType)
+            nssiNeedHandlerMap.put("nsstInfo", sliceTaskParams.cnSliceTaskInfo.NSSTInfo)
+            nssiNeedHandlerMap.put("sliceProfile", sliceTaskParams.cnSliceTaskInfo.sliceProfile)
+            nssiNeedHandlerInfos.add(nssiNeedHandlerMap)
+        }
+        if (needAnNssiSelection) {
+            nssiNeedHandlerMap.clear()
+            nssiNeedHandlerMap.put("subnetType", sliceTaskParams.anSliceTaskInfo.subnetType)
+            nssiNeedHandlerMap.put("nsstInfo", sliceTaskParams.anSliceTaskInfo.NSSTInfo)
+            nssiNeedHandlerMap.put("sliceProfile", sliceTaskParams.anSliceTaskInfo.sliceProfile)
+            nssiNeedHandlerInfos.add(nssiNeedHandlerMap)
+        }
+        if (needTnNssiSelection) {
+            nssiNeedHandlerMap.clear()
+            nssiNeedHandlerMap.put("subnetType", sliceTaskParams.tnBHSliceTaskInfo.subnetType)
+            nssiNeedHandlerMap.put("nsstInfo", sliceTaskParams.tnBHSliceTaskInfo.NSSTInfo)
+            nssiNeedHandlerMap.put("sliceProfile", sliceTaskParams.tnBHSliceTaskInfo.sliceProfile)
+            nssiNeedHandlerInfos.add(nssiNeedHandlerMap)
+
+            nssiNeedHandlerMap.clear()
+            nssiNeedHandlerMap.put("subnetType", sliceTaskParams.tnMHSliceTaskInfo.subnetType)
+            nssiNeedHandlerMap.put("nsstInfo", sliceTaskParams.tnMHSliceTaskInfo.NSSTInfo)
+            nssiNeedHandlerMap.put("sliceProfile", sliceTaskParams.tnMHSliceTaskInfo.sliceProfile)
+            nssiNeedHandlerInfos.add(nssiNeedHandlerMap)
+
+            nssiNeedHandlerMap.clear()
+            nssiNeedHandlerMap.put("subnetType", sliceTaskParams.tnFHSliceTaskInfo.subnetType)
+            nssiNeedHandlerMap.put("nsstInfo", sliceTaskParams.tnFHSliceTaskInfo.NSSTInfo)
+            nssiNeedHandlerMap.put("sliceProfile", sliceTaskParams.tnFHSliceTaskInfo.sliceProfile)
+            nssiNeedHandlerInfos.add(nssiNeedHandlerMap)
+
+        }
+
+        if (nssiNeedHandlerInfos.size() > 0) {
+            execution.setVariable("needSelectNssi", true)
+            execution.setVariable("currNssiIndex", 0)
+            execution.setVariable("nssiNeedHandlerInfos", nssiNeedHandlerInfos)
+        } else {
+            execution.setVariable("needSelectNssi", false)
+        }
+
+        execution.setVariable("sliceTaskParams", sliceTaskParams)
     }
 
     /**
-     * todo: need rewrite
      * prepare select nssi request
      * @param execution
      */
     public void preNSSIRequest(DelegateExecution execution) {
 
+        List<Map> nssiNeedHandlerInfos =
+                execution.getVariable("nssiNeedHandlerInfos") as List<Map>
+
+        int currNssiIndex = execution.getVariable("currNssiIndex") as Integer
+        Map nssiNeedHandlerInfo = nssiNeedHandlerInfos.get(currNssiIndex) as Map
+
+        TemplateInfo nsstInfo = nssiNeedHandlerInfo.get("nsstInfo") as TemplateInfo
+        Object profileInfo = nssiNeedHandlerInfo.get("sliceProfile")
+
         String urlString = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution)
         logger.debug( "get NSI option OOF Url: " + urlString)
 
-        boolean isNSISuggested = true
-        execution.setVariable("isNSISuggested", isNSISuggested)
         String requestId = execution.getVariable("msoRequestId")
-        String messageType = "NSISelectionResponse"
+        String messageType = "NSSISelectionResponse"
 
-        Map<String, Object> profileInfo = execution.getVariable("serviceProfile") as Map
-        Map<String, Object> nstSolution = execution.getVariable("nstSolution") as Map
-        logger.debug("Get NST selection from OOF: " + nstSolution.toString())
-        String nstInfo = """{
-            "modelInvariantId":"${nstSolution.invariantUUID}",
-            "modelVersionId":"${nstSolution.UUID}",
-            "modelName":"${nstSolution.NSTName}"
-         }"""
-
-        execution.setVariable("nsiSelectionUrl", "/api/oof/selection/nsi/v1")
-        execution.setVariable("nsiSelection_messageType", messageType)
-        execution.setVariable("nsiSelection_correlator", requestId)
+        execution.setVariable("nssiSelectionUrl", "/api/oof/selection/nssi/v1")
+        execution.setVariable("nssiSelection_messageType", messageType)
+        execution.setVariable("nssiSelection_correlator", requestId)
         String timeout = UrnPropertiesReader.getVariable("mso.adapters.oof.timeout", execution)
-        execution.setVariable("nsiSelection_timeout", timeout)
+        execution.setVariable("nssiSelection_timeout", timeout)
 
-        //todo
-        String oofRequest = oofUtils.buildSelectNSIRequest(requestId, nstInfo, messageType, profileInfo)
+        String oofRequest = oofUtils.buildSelectNSSIRequest(requestId, nsstInfo, messageType,
+                profileInfo, timeout as Integer)
 
-        execution.setVariable("nsiSelection_oofRequest", oofRequest)
+        execution.setVariable("nssiSelection_oofRequest", oofRequest)
         logger.debug("Sending request to OOF: " + oofRequest)
     }
 
     /**
      * process select nssi response
-     * todo: unfinished
      * @param execution
      */
     public void processNSSIResp(DelegateExecution execution) {
 
-        SliceTaskParams sliceTaskParams = execution.getVariable("sliceTaskParams") as SliceTaskParams
-        String OOFResponse = execution.getVariable("nsiSelection_oofResponse")
+        List<Map> nssiNeedHandlerInfos =
+                execution.getVariable("nssiNeedHandlerInfos") as List<Map>
+
+        int currNssiIndex = execution.getVariable("currNssiIndex") as Integer
+        Map nssiNeedHandlerInfo = nssiNeedHandlerInfos.get(currNssiIndex) as Map
+        SubnetType subnetType = nssiNeedHandlerInfo.get("subnetType") as SubnetType
+
+        SliceTaskParamsAdapter sliceTaskParams =
+                execution.getVariable("sliceTaskParams") as SliceTaskParamsAdapter
+
+
+        String OOFResponse = execution.getVariable("nssiSelection_oofResponse")
         logger.debug("NSI OOFResponse is: " + OOFResponse)
         execution.setVariable("OOFResponse", OOFResponse)
         //This needs to be changed to derive a value when we add policy to decide the solution options.
 
         Map<String, Object> resMap = objectMapper.readValue(OOFResponse, Map.class)
         List<Map<String, Object>> nsiSolutions = (List<Map<String, Object>>) resMap.get("solutions")
-        Map<String, Object> solutions = nsiSolutions.get(0)
+        Map<String, Object> solution = nsiSolutions.get(0)
 
         String resourceSharingLevel = execution.getVariable("resourceSharingLevel")
-        Boolean isSharable = resourceSharingLevel == "shared"
+        Boolean isSharable = resourceSharingLevel == "shared"   //todo
 
-        if (solutions != null) {
-            if (isSharable && solutions.get("existingNSI")) {
-                //sharedNSISolution
-                //processSharedNSISolutions(solutions, execution)
-            }
-            else if(solutions.containsKey("newNSISolution")) {
-                //processNewNSISolutions(solutions, execution)
-            }
+        if (isSharable && solution != null) {
+            processNssiResult(sliceTaskParams, subnetType, solution)
         }
+
         execution.setVariable("sliceTaskParams", sliceTaskParams)
-        logger.debug("sliceTaskParams: "+sliceTaskParams.convertToJson())
+        //logger.debug("sliceTaskParams: "+ sliceTaskParams.convertToJson())
         logger.debug("*** Completed options Call to OOF ***")
 
         logger.debug("start parseServiceProfile")
         //parseServiceProfile(execution)
         logger.debug("end parseServiceProfile")
+
+        if (currNssiIndex >= nssiNeedHandlerInfos.size() - 1) {
+            execution.setVariable("needSelectNssi", false)
+        } else {
+            execution.setVariable("currNssiIndex", currNssiIndex + 1)
+            execution.setVariable("needSelectNssi", true)
+        }
+
     }
 
+    private void processNssiResult(SliceTaskParamsAdapter sliceTaskParams, SubnetType subnetType,
+                                   Map<String, Object> solution) {
+        switch (subnetType) {
+            case SubnetType.CN:
+                sliceTaskParams.cnSliceTaskInfo.suggestNssiId = solution.get("NSSIId")
+                sliceTaskParams.cnSliceTaskInfo.suggestNssiName = solution.get("NSSIName")
+                break
+            case SubnetType.AN_NF:
+                sliceTaskParams.anSliceTaskInfo.suggestNssiId = solution.get("NSSIId")
+                sliceTaskParams.anSliceTaskInfo.suggestNssiName = solution.get("NSSIName")
+                break
+            case SubnetType.TN_BH:
+                sliceTaskParams.tnBHSliceTaskInfo.suggestNssiId = solution.get("NSSIId")
+                sliceTaskParams.tnBHSliceTaskInfo.suggestNssiName = solution.get("NSSIName")
+                break
+            case SubnetType.TN_FH:
+                sliceTaskParams.tnFHSliceTaskInfo.suggestNssiId = solution.get("NSSIId")
+                sliceTaskParams.tnFHSliceTaskInfo.suggestNssiName = solution.get("NSSIName")
+                break
+            case SubnetType.TN_MH:
+                sliceTaskParams.tnMHSliceTaskInfo.suggestNssiId = solution.get("NSSIId")
+                sliceTaskParams.tnMHSliceTaskInfo.suggestNssiName = solution.get("NSSIName")
+                break
+        }
+    }
 
 }
index 60d7355..9656c86 100644 (file)
@@ -42,6 +42,8 @@ css.processUserOptions(execution)</bpmn:script>
         <camunda:out source="rolledBack" target="rolledBack" />
         <camunda:out source="serviceInstanceData" target="serviceInstanceData" />
         <camunda:in source="sliceTaskParams" target="sliceTaskParams" />
+        <camunda:in source="sliceTaskParams" target="sliceTaskParams" />
+        <camunda:out source="sliceTaskParams" target="sliceTaskParams" />
       </bpmn:extensionElements>
       <bpmn:incoming>SequenceFlow_1dfon41</bpmn:incoming>
       <bpmn:outgoing>SequenceFlow_0jhqtls</bpmn:outgoing>
@@ -278,6 +280,7 @@ css.prepareUpdateOrchestrationTask(execution)</bpmn:script>
         <camunda:out source="rollbackData" target="rollbackData" />
         <camunda:out source="rolledBack" target="rolledBack" />
         <camunda:in source="allottedResourceId" target="allottedResourceId" />
+        <camunda:out source="sliceTaskParams" target="sliceTaskParams" />
       </bpmn:extensionElements>
       <bpmn:incoming>SequenceFlow_1bevt3a</bpmn:incoming>
       <bpmn:outgoing>SequenceFlow_0mlrlbv</bpmn:outgoing>
index e42f001..9090bf2 100644 (file)
@@ -58,19 +58,11 @@ dcnsio.createNSIinAAI(execution)</bpmn:script>
     <bpmn:callActivity id="CallActivity_1yh9tiq" name="Call DoAllocateNSSI(RAN)" calledElement="DoAllocateNSSI">
       <bpmn:extensionElements>
         <camunda:in source="msoRequestId" target="msoRequestId" />
-        <camunda:out source="serviceDecomposition" target="serviceDecomposition" />
         <camunda:out source="WorkflowException" target="WorkflowException" />
         <camunda:in source="nsstInput" target="nsstInput" />
-        <camunda:in source="serviceProfile" target="serviceProfile" />
-        <camunda:in source="sliceProfileTn" target="sliceProfileTn" />
-        <camunda:in source="sliceProfileCn" target="sliceProfileCn" />
-        <camunda:in source="sliceProfileAn" target="sliceProfileAn" />
         <camunda:in source="globalSubscriberId" target="globalSubscriberId" />
         <camunda:in source="subscriptionServiceType" target="subscriptionServiceType" />
         <camunda:in source="uuiRequest" target="uuiRequest" />
-        <camunda:in source="nsiServiceInstanceId" target="nsiServiceInstanceId" />
-        <camunda:in source="nsiServiceInstanceName" target="nsiServiceInstanceName" />
-        <camunda:in source="nssiserviceModelInfo" target="nssiserviceModelInfo" />
         <camunda:in source="sliceTaskParams" target="sliceTaskParams" />
         <camunda:in source="taskId" target="CSSOT_taskId" />
         <camunda:in source="taskName" target="CSSOT_name" />
@@ -80,6 +72,8 @@ dcnsio.createNSIinAAI(execution)</bpmn:script>
         <camunda:in source="anSliceTaskInfo" target="sliceTaskInfo" />
         <camunda:out source="nssiAllocateResult" target="anNssiAllocateResult" />
         <camunda:in source="AnAllocateNssiNbiRequest" target="nbiRequest" />
+        <camunda:out source="sliceTaskParams" target="sliceTaskParams" />
+        <camunda:in source="anSubnetType" target="subnetType" />
       </bpmn:extensionElements>
       <bpmn:incoming>SequenceFlow_0npsyye</bpmn:incoming>
       <bpmn:outgoing>SequenceFlow_1xb5nx1</bpmn:outgoing>
@@ -88,19 +82,11 @@ dcnsio.createNSIinAAI(execution)</bpmn:script>
     <bpmn:callActivity id="CallActivity_1ixah3o" name="Call DoAllocateNSSI(Core)" calledElement="DoAllocateNSSI">
       <bpmn:extensionElements>
         <camunda:in source="msoRequestId" target="msoRequestId" />
-        <camunda:out source="serviceDecomposition" target="serviceDecomposition" />
         <camunda:out source="WorkflowException" target="WorkflowException" />
         <camunda:in source="nsstInput" target="nsstInput" />
-        <camunda:in source="serviceProfile" target="serviceProfile" />
-        <camunda:in source="sliceProfileTn" target="sliceProfileTn" />
-        <camunda:in source="sliceProfileCn" target="sliceProfileCn" />
-        <camunda:in source="sliceProfileAn" target="sliceProfileAn" />
         <camunda:in source="globalSubscriberId" target="globalSubscriberId" />
         <camunda:in source="subscriptionServiceType" target="subscriptionServiceType" />
         <camunda:in source="uuiRequest" target="uuiRequest" />
-        <camunda:in source="nsiServiceInstanceId" target="nsiServiceInstanceId" />
-        <camunda:in source="nsiServiceInstanceName" target="nsiServiceInstanceName" />
-        <camunda:in source="nssiserviceModelInfo" target="nssiserviceModelInfo" />
         <camunda:in source="sliceTaskParams" target="sliceTaskParams" />
         <camunda:in source="taskId" target="CSSOT_taskId" />
         <camunda:in source="taskName" target="CSSOT_name" />
@@ -111,6 +97,8 @@ dcnsio.createNSIinAAI(execution)</bpmn:script>
         <camunda:in source="domainType" target="domainType" />
         <camunda:out source="nssiAllocateResult" target="cnNssiAllocateResult" />
         <camunda:in source="CnAllocateNssiNbiRequest" target="nbiRequest" />
+        <camunda:out source="sliceTaskParams" target="sliceTaskParams" />
+        <camunda:in source="cnSubnetType" target="subnetType" />
       </bpmn:extensionElements>
       <bpmn:incoming>SequenceFlow_0cwbtmr</bpmn:incoming>
       <bpmn:outgoing>SequenceFlow_1l74seh</bpmn:outgoing>
@@ -185,19 +173,11 @@ dcnsio.createTnBHSliceProfile(execution)</bpmn:script>
     <bpmn:callActivity id="CallActivity_0b28wlb" name="Call DoAllocateNSSI(TN)" calledElement="DoAllocateNSSI">
       <bpmn:extensionElements>
         <camunda:in source="msoRequestId" target="msoRequestId" />
-        <camunda:out source="serviceDecomposition" target="serviceDecomposition" />
         <camunda:out source="WorkflowException" target="WorkflowException" />
         <camunda:in source="nsstInput" target="nsstInput" />
-        <camunda:in source="serviceProfile" target="serviceProfile" />
-        <camunda:in source="sliceProfileTn" target="sliceProfileTn" />
-        <camunda:in source="sliceProfileCn" target="sliceProfileCn" />
-        <camunda:in source="sliceProfileAn" target="sliceProfileAn" />
         <camunda:in source="globalSubscriberId" target="globalSubscriberId" />
         <camunda:in source="subscriptionServiceType" target="subscriptionServiceType" />
         <camunda:in source="uuiRequest" target="uuiRequest" />
-        <camunda:in source="nsiServiceInstanceId" target="nsiServiceInstanceId" />
-        <camunda:in source="nsiServiceInstanceName" target="nsiServiceInstanceName" />
-        <camunda:in source="nssiserviceModelInfo" target="nssiserviceModelInfo" />
         <camunda:in source="sliceTaskParams" target="sliceTaskParams" />
         <camunda:in source="taskId" target="CSSOT_taskId" />
         <camunda:in source="taskName" target="CSSOT_name" />
@@ -207,6 +187,8 @@ dcnsio.createTnBHSliceProfile(execution)</bpmn:script>
         <camunda:in source="tnBHSliceTaskInfo" target="sliceTaskInfo" />
         <camunda:out source="nssiAllocateResult" target="tnBHNssiAllocateResult" />
         <camunda:in source="TnBHAllocateNssiNbiRequest" target="nbiRequest" />
+        <camunda:out source="sliceTaskParams" target="sliceTaskParams" />
+        <camunda:in source="tnBHSubnetType" target="subnetType" />
       </bpmn:extensionElements>
       <bpmn:incoming>SequenceFlow_01isn2q</bpmn:incoming>
       <bpmn:outgoing>SequenceFlow_1omynpt</bpmn:outgoing>
@@ -279,7 +261,7 @@ dcnsio.prepareAllocateTnBHNssi(execution)</bpmn:script>
   </bpmn:process>
   <bpmn:message id="Message_1i10pf1" name="Message_2mc69tg" />
   <bpmndi:BPMNDiagram id="BPMNDiagram_1">
-    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="DoAllocateNSIandNSSIV2">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="DoAllocateNSIandNSSI">
       <bpmndi:BPMNShape id="StartEvent_1ym3sha_di" bpmnElement="StartEvent_1ym3sha">
         <dc:Bounds x="138" y="122" width="36" height="36" />
         <bpmndi:BPMNLabel>
index 6e94538..5879505 100644 (file)
@@ -76,7 +76,7 @@ dcnssi.timeDelay(execution)</bpmn:script>
     </bpmn:endEvent>
   </bpmn:process>
   <bpmndi:BPMNDiagram id="BPMNDiagram_1">
-    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="DoAllocateNSSIV2">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="DoAllocateNSSI">
       <bpmndi:BPMNShape id="StartEvent_0zs8ezi_di" bpmnElement="StartEvent_0zs8ezi">
         <dc:Bounds x="147" y="112" width="36" height="36" />
         <bpmndi:BPMNLabel>
@@ -155,4 +155,4 @@ dcnssi.timeDelay(execution)</bpmn:script>
       </bpmndi:BPMNShape>
     </bpmndi:BPMNPlane>
   </bpmndi:BPMNDiagram>
-</bpmn:definitions>
+</bpmn:definitions>
\ No newline at end of file
index 0345ea7..2aa7da2 100644 (file)
@@ -25,7 +25,7 @@ dcsi.preProcessRequest(execution)</bpmn:script>
       <bpmn:outgoing>SequenceFlow_0g5bwvl</bpmn:outgoing>
       <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
 def dcsi = new DoCreateSliceServiceInstance()
-dcsi.instantiateSliceService(execution)</bpmn:script>
+dcsi.createServiceProfileInstance(execution)</bpmn:script>
     </bpmn:scriptTask>
     <bpmn:endEvent id="EndEvent_1x6k78c">
       <bpmn:incoming>SequenceFlow_1uiz85h</bpmn:incoming>
@@ -135,4 +135,4 @@ dcsi.prepareDecomposeService(execution)</bpmn:script>
       </bpmndi:BPMNEdge>
     </bpmndi:BPMNPlane>
   </bpmndi:BPMNDiagram>
-</bpmn:definitions>
+</bpmn:definitions>
\ No newline at end of file
index 045d88d..1bda596 100644 (file)
@@ -29,43 +29,19 @@ dcso.processDecompositionNST(execution)</bpmn:script>
     </bpmn:scriptTask>
     <bpmn:sequenceFlow id="SequenceFlow_1kzy63m" sourceRef="ScriptTask_11rb2ju" targetRef="CallActivity_0c567r4" />
     <bpmn:sequenceFlow id="SequenceFlow_1t317y2" sourceRef="CallActivity_0c567r4" targetRef="ScriptTask_0z0dwk2" />
-    <bpmn:parallelGateway id="ParallelGateway_05zg916">
-      <bpmn:incoming>SequenceFlow_1h3kdce</bpmn:incoming>
-      <bpmn:outgoing>SequenceFlow_05250mp</bpmn:outgoing>
-      <bpmn:outgoing>SequenceFlow_0euwvgf</bpmn:outgoing>
-      <bpmn:outgoing>SequenceFlow_0il5j01</bpmn:outgoing>
-    </bpmn:parallelGateway>
-    <bpmn:parallelGateway id="ParallelGateway_06a2n9u">
-      <bpmn:incoming>SequenceFlow_14rhmx9</bpmn:incoming>
-      <bpmn:incoming>SequenceFlow_103oxyw</bpmn:incoming>
-      <bpmn:incoming>SequenceFlow_0aasemn</bpmn:incoming>
-      <bpmn:outgoing>SequenceFlow_1tr3i9d</bpmn:outgoing>
-    </bpmn:parallelGateway>
-    <bpmn:callActivity id="CallActivity_0tzazs0" name="Handle NSST Selection OOF request" calledElement="DoHandleOofRequest">
+    <bpmn:callActivity id="CallActivity_0tzazs0" name="Handle NSSI Selection OOF request" calledElement="DoHandleOofRequest">
       <bpmn:extensionElements>
-        <camunda:in source="nstSelectionUrl" target="apiPath" />
-        <camunda:in source="nstSelection_correlator" target="correlator" />
-        <camunda:in source="nstSelection_messageType" target="messageType" />
-        <camunda:in source="nstSelection_timeout" target="timeout" />
+        <camunda:in source="nssiSelectionUrl" target="apiPath" />
+        <camunda:in source="nssiSelection_correlator" target="correlator" />
+        <camunda:in source="nssiSelection_messageType" target="messageType" />
+        <camunda:in source="nssiSelection_timeout" target="timeout" />
         <camunda:out source="WorkflowException" target="WorkflowException" />
-        <camunda:out source="asyncCallbackResponse" target="nstSelection_oofResponse" />
-        <camunda:in source="nstSelection_oofRequest" target="oofRequest" />
+        <camunda:out source="asyncCallbackResponse" target="nssiSelection_oofResponse" />
+        <camunda:in source="nssiSelection_oofRequest" target="oofRequest" />
       </bpmn:extensionElements>
       <bpmn:incoming>SequenceFlow_0abqxa1</bpmn:incoming>
       <bpmn:outgoing>SequenceFlow_1tqg26p</bpmn:outgoing>
     </bpmn:callActivity>
-    <bpmn:sequenceFlow id="SequenceFlow_05250mp" sourceRef="ParallelGateway_05zg916" targetRef="CallActivity_1vzxvna" />
-    <bpmn:sequenceFlow id="SequenceFlow_14rhmx9" sourceRef="CallActivity_1vzxvna" targetRef="ParallelGateway_06a2n9u" />
-    <bpmn:sequenceFlow id="SequenceFlow_0euwvgf" sourceRef="ParallelGateway_05zg916" targetRef="CallActivity_0melx8d" />
-    <bpmn:sequenceFlow id="SequenceFlow_103oxyw" sourceRef="CallActivity_0melx8d" targetRef="ParallelGateway_06a2n9u" />
-    <bpmn:sequenceFlow id="SequenceFlow_0il5j01" sourceRef="ParallelGateway_05zg916" targetRef="CallActivity_0otry7e" />
-    <bpmn:sequenceFlow id="SequenceFlow_0aasemn" sourceRef="CallActivity_0otry7e" targetRef="ParallelGateway_06a2n9u" />
-    <bpmn:sequenceFlow id="SequenceFlow_1tr3i9d" sourceRef="ParallelGateway_06a2n9u" targetRef="Task_1jyj2vs" />
-    <bpmn:sequenceFlow id="SequenceFlow_0abqxa1" sourceRef="Task_1m9qoo3" targetRef="CallActivity_0tzazs0" />
-    <bpmn:sequenceFlow id="SequenceFlow_1tqg26p" sourceRef="CallActivity_0tzazs0" targetRef="Task_00nfg5x" />
-    <bpmn:endEvent id="EndEvent_0p0cjhl">
-      <bpmn:incoming>SequenceFlow_1nrfy6i</bpmn:incoming>
-    </bpmn:endEvent>
     <bpmn:startEvent id="StartEvent_0mwlirs" name="Start">
       <bpmn:outgoing>SequenceFlow_1fuwy35</bpmn:outgoing>
     </bpmn:startEvent>
@@ -107,29 +83,10 @@ dcso.preNSSIRequest(execution)</bpmn:script>
     </bpmn:scriptTask>
     <bpmn:scriptTask id="Task_00nfg5x" name="Process NSST Solutions" scriptFormat="groovy">
       <bpmn:incoming>SequenceFlow_1tqg26p</bpmn:incoming>
-      <bpmn:outgoing>SequenceFlow_1i3j8c3</bpmn:outgoing>
+      <bpmn:outgoing>SequenceFlow_1ezi1oi</bpmn:outgoing>
       <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
 def dcso = new DoCreateSliceServiceOption()
 dcso.processNSSIResp(execution)</bpmn:script>
-    </bpmn:scriptTask>
-    <bpmn:exclusiveGateway id="ExclusiveGateway_0b52m39" name="need select nssi?" default="SequenceFlow_1nrfy6i">
-      <bpmn:incoming>SequenceFlow_1tey3hz</bpmn:incoming>
-      <bpmn:outgoing>SequenceFlow_126j77n</bpmn:outgoing>
-      <bpmn:outgoing>SequenceFlow_1nrfy6i</bpmn:outgoing>
-    </bpmn:exclusiveGateway>
-    <bpmn:sequenceFlow id="SequenceFlow_126j77n" name="yes" sourceRef="ExclusiveGateway_0b52m39" targetRef="Task_1m9qoo3">
-      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{(execution.getVariable("nssmfOperation" )  == "update")}</bpmn:conditionExpression>
-    </bpmn:sequenceFlow>
-    <bpmn:sequenceFlow id="SequenceFlow_1nrfy6i" sourceRef="ExclusiveGateway_0b52m39" targetRef="EndEvent_0p0cjhl" />
-    <bpmn:sequenceFlow id="SequenceFlow_1i3j8c3" sourceRef="Task_00nfg5x" targetRef="Task_1jyj2vs" />
-    <bpmn:sequenceFlow id="SequenceFlow_1tey3hz" sourceRef="Task_1jyj2vs" targetRef="ExclusiveGateway_0b52m39" />
-    <bpmn:scriptTask id="Task_1jyj2vs" name="handle Nssi select " scriptFormat="groovy">
-      <bpmn:incoming>SequenceFlow_1tr3i9d</bpmn:incoming>
-      <bpmn:incoming>SequenceFlow_1i3j8c3</bpmn:incoming>
-      <bpmn:outgoing>SequenceFlow_1tey3hz</bpmn:outgoing>
-      <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
-def dcso = new DoCreateSliceServiceOption()
-dcso.handleNssiSelect(execution)</bpmn:script>
     </bpmn:scriptTask>
     <bpmn:scriptTask id="ScriptTask_12sydez" name="prepare NSST decomposition" scriptFormat="groovy">
       <bpmn:incoming>SequenceFlow_0zglfyw</bpmn:incoming>
@@ -206,7 +163,7 @@ dcso.processNSIResp(execution)</bpmn:script>
       <bpmn:outgoing>SequenceFlow_14o0fxe</bpmn:outgoing>
       <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
 def dcso = new DoCreateSliceServiceOption()
-dcso.preNSIRequest(execution)</bpmn:script>
+dcso.preNSIRequest(execution,true)</bpmn:script>
     </bpmn:scriptTask>
     <bpmn:intermediateCatchEvent id="IntermediateCatchEvent_00uke3g" name=" Select NSSI ">
       <bpmn:outgoing>SequenceFlow_1iawj3m</bpmn:outgoing>
@@ -215,10 +172,53 @@ dcso.preNSIRequest(execution)</bpmn:script>
     <bpmn:sequenceFlow id="SequenceFlow_14o0fxe" sourceRef="ScriptTask_0bgvphs" targetRef="CallActivity_0vs5jgq" />
     <bpmn:sequenceFlow id="SequenceFlow_0nwt0ci" sourceRef="CallActivity_0vs5jgq" targetRef="ScriptTask_12t6v71" />
     <bpmn:sequenceFlow id="SequenceFlow_1iawj3m" sourceRef="IntermediateCatchEvent_00uke3g" targetRef="ScriptTask_0bgvphs" />
+    <bpmn:scriptTask id="Task_1jyj2vs" name="handle Nssi select " scriptFormat="groovy">
+      <bpmn:incoming>SequenceFlow_1tr3i9d</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_1tey3hz</bpmn:outgoing>
+      <bpmn:script>import org.onap.so.bpmn.infrastructure.scripts.*
+def dcso = new DoCreateSliceServiceOption()
+dcso.handleNssiSelect(execution)</bpmn:script>
+    </bpmn:scriptTask>
+    <bpmn:parallelGateway id="ParallelGateway_06a2n9u">
+      <bpmn:incoming>SequenceFlow_0aasemn</bpmn:incoming>
+      <bpmn:incoming>SequenceFlow_103oxyw</bpmn:incoming>
+      <bpmn:incoming>SequenceFlow_14rhmx9</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_1tr3i9d</bpmn:outgoing>
+    </bpmn:parallelGateway>
+    <bpmn:sequenceFlow id="SequenceFlow_1tr3i9d" sourceRef="ParallelGateway_06a2n9u" targetRef="Task_1jyj2vs" />
+    <bpmn:sequenceFlow id="SequenceFlow_0aasemn" sourceRef="CallActivity_0otry7e" targetRef="ParallelGateway_06a2n9u" />
+    <bpmn:sequenceFlow id="SequenceFlow_103oxyw" sourceRef="CallActivity_0melx8d" targetRef="ParallelGateway_06a2n9u" />
+    <bpmn:sequenceFlow id="SequenceFlow_14rhmx9" sourceRef="CallActivity_1vzxvna" targetRef="ParallelGateway_06a2n9u" />
+    <bpmn:parallelGateway id="ParallelGateway_05zg916">
+      <bpmn:incoming>SequenceFlow_1h3kdce</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_0il5j01</bpmn:outgoing>
+      <bpmn:outgoing>SequenceFlow_0euwvgf</bpmn:outgoing>
+      <bpmn:outgoing>SequenceFlow_05250mp</bpmn:outgoing>
+    </bpmn:parallelGateway>
+    <bpmn:sequenceFlow id="SequenceFlow_0il5j01" sourceRef="ParallelGateway_05zg916" targetRef="CallActivity_0otry7e" />
+    <bpmn:sequenceFlow id="SequenceFlow_0euwvgf" sourceRef="ParallelGateway_05zg916" targetRef="CallActivity_0melx8d" />
+    <bpmn:sequenceFlow id="SequenceFlow_05250mp" sourceRef="ParallelGateway_05zg916" targetRef="CallActivity_1vzxvna" />
     <bpmn:sequenceFlow id="SequenceFlow_1h3kdce" sourceRef="ScriptTask_12t6v71" targetRef="ParallelGateway_05zg916" />
+    <bpmn:sequenceFlow id="SequenceFlow_1tqg26p" sourceRef="CallActivity_0tzazs0" targetRef="Task_00nfg5x" />
+    <bpmn:sequenceFlow id="SequenceFlow_1tey3hz" sourceRef="Task_1jyj2vs" targetRef="ExclusiveGateway_0b52m39" />
+    <bpmn:sequenceFlow id="SequenceFlow_0abqxa1" sourceRef="Task_1m9qoo3" targetRef="CallActivity_0tzazs0" />
+    <bpmn:exclusiveGateway id="ExclusiveGateway_0b52m39" name="need select nssi?" default="SequenceFlow_1nrfy6i">
+      <bpmn:incoming>SequenceFlow_1tey3hz</bpmn:incoming>
+      <bpmn:incoming>SequenceFlow_1ezi1oi</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_126j77n</bpmn:outgoing>
+      <bpmn:outgoing>SequenceFlow_1nrfy6i</bpmn:outgoing>
+    </bpmn:exclusiveGateway>
+    <bpmn:sequenceFlow id="SequenceFlow_126j77n" name="yes" sourceRef="ExclusiveGateway_0b52m39" targetRef="Task_1m9qoo3">
+      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{(execution.getVariable("needSelectNssi" )  == true)}</bpmn:conditionExpression>
+    </bpmn:sequenceFlow>
+    <bpmn:endEvent id="EndEvent_0p0cjhl">
+      <bpmn:incoming>SequenceFlow_1nrfy6i</bpmn:incoming>
+    </bpmn:endEvent>
+    <bpmn:sequenceFlow id="SequenceFlow_1nrfy6i" sourceRef="ExclusiveGateway_0b52m39" targetRef="EndEvent_0p0cjhl" />
+    <bpmn:sequenceFlow id="SequenceFlow_1ezi1oi" sourceRef="Task_00nfg5x" targetRef="ExclusiveGateway_0b52m39" />
   </bpmn:process>
   <bpmndi:BPMNDiagram id="BPMNDiagram_1">
-    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="DoCreateSliceServiceOptionV2">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="DoCreateSliceServiceOption">
       <bpmndi:BPMNShape id="ScriptTask_11rb2ju_di" bpmnElement="ScriptTask_11rb2ju">
         <dc:Bounds x="400" y="140" width="100" height="80" />
       </bpmndi:BPMNShape>
@@ -236,58 +236,9 @@ dcso.preNSIRequest(execution)</bpmn:script>
         <di:waypoint x="660" y="180" />
         <di:waypoint x="710" y="180" />
       </bpmndi:BPMNEdge>
-      <bpmndi:BPMNShape id="ParallelGateway_05zg916_di" bpmnElement="ParallelGateway_05zg916">
-        <dc:Bounds x="635" y="475" width="50" height="50" />
-      </bpmndi:BPMNShape>
-      <bpmndi:BPMNShape id="ParallelGateway_06a2n9u_di" bpmnElement="ParallelGateway_06a2n9u">
-        <dc:Bounds x="905" y="475" width="50" height="50" />
-      </bpmndi:BPMNShape>
       <bpmndi:BPMNShape id="CallActivity_0tzazs0_di" bpmnElement="CallActivity_0tzazs0">
         <dc:Bounds x="1410" y="320" width="100" height="80" />
       </bpmndi:BPMNShape>
-      <bpmndi:BPMNEdge id="SequenceFlow_05250mp_di" bpmnElement="SequenceFlow_05250mp">
-        <di:waypoint x="660" y="475" />
-        <di:waypoint x="660" y="360" />
-        <di:waypoint x="740" y="360" />
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge id="SequenceFlow_14rhmx9_di" bpmnElement="SequenceFlow_14rhmx9">
-        <di:waypoint x="840" y="360" />
-        <di:waypoint x="930" y="360" />
-        <di:waypoint x="930" y="475" />
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge id="SequenceFlow_0euwvgf_di" bpmnElement="SequenceFlow_0euwvgf">
-        <di:waypoint x="685" y="500" />
-        <di:waypoint x="740" y="500" />
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge id="SequenceFlow_103oxyw_di" bpmnElement="SequenceFlow_103oxyw">
-        <di:waypoint x="840" y="500" />
-        <di:waypoint x="905" y="500" />
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge id="SequenceFlow_0il5j01_di" bpmnElement="SequenceFlow_0il5j01">
-        <di:waypoint x="660" y="525" />
-        <di:waypoint x="660" y="620" />
-        <di:waypoint x="740" y="620" />
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge id="SequenceFlow_0aasemn_di" bpmnElement="SequenceFlow_0aasemn">
-        <di:waypoint x="840" y="620" />
-        <di:waypoint x="930" y="620" />
-        <di:waypoint x="930" y="525" />
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge id="SequenceFlow_1tr3i9d_di" bpmnElement="SequenceFlow_1tr3i9d">
-        <di:waypoint x="955" y="500" />
-        <di:waypoint x="1010" y="500" />
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge id="SequenceFlow_0abqxa1_di" bpmnElement="SequenceFlow_0abqxa1">
-        <di:waypoint x="1460" y="460" />
-        <di:waypoint x="1460" y="400" />
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge id="SequenceFlow_1tqg26p_di" bpmnElement="SequenceFlow_1tqg26p">
-        <di:waypoint x="1410" y="360" />
-        <di:waypoint x="1110" y="360" />
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNShape id="EndEvent_0p0cjhl_di" bpmnElement="EndEvent_0p0cjhl">
-        <dc:Bounds x="1442" y="602" width="36" height="36" />
-      </bpmndi:BPMNShape>
       <bpmndi:BPMNShape id="StartEvent_0mwlirs_di" bpmnElement="StartEvent_0mwlirs">
         <dc:Bounds x="162" y="162" width="36" height="36" />
         <bpmndi:BPMNLabel>
@@ -314,36 +265,7 @@ dcso.preNSIRequest(execution)</bpmn:script>
         <dc:Bounds x="1410" y="460" width="100" height="80" />
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape id="ScriptTask_0aqbm7t_di" bpmnElement="Task_00nfg5x">
-        <dc:Bounds x="1010" y="320" width="100" height="80" />
-      </bpmndi:BPMNShape>
-      <bpmndi:BPMNShape id="ExclusiveGateway_0b52m39_di" bpmnElement="ExclusiveGateway_0b52m39" isMarkerVisible="true">
-        <dc:Bounds x="1235" y="475" width="50" height="50" />
-        <bpmndi:BPMNLabel>
-          <dc:Bounds x="1218" y="463" width="85" height="14" />
-        </bpmndi:BPMNLabel>
-      </bpmndi:BPMNShape>
-      <bpmndi:BPMNEdge id="SequenceFlow_126j77n_di" bpmnElement="SequenceFlow_126j77n">
-        <di:waypoint x="1285" y="500" />
-        <di:waypoint x="1410" y="500" />
-        <bpmndi:BPMNLabel>
-          <dc:Bounds x="1339" y="482" width="17" height="14" />
-        </bpmndi:BPMNLabel>
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge id="SequenceFlow_1nrfy6i_di" bpmnElement="SequenceFlow_1nrfy6i">
-        <di:waypoint x="1260" y="525" />
-        <di:waypoint x="1260" y="620" />
-        <di:waypoint x="1442" y="620" />
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge id="SequenceFlow_1i3j8c3_di" bpmnElement="SequenceFlow_1i3j8c3">
-        <di:waypoint x="1060" y="400" />
-        <di:waypoint x="1060" y="460" />
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge id="SequenceFlow_1tey3hz_di" bpmnElement="SequenceFlow_1tey3hz">
-        <di:waypoint x="1110" y="500" />
-        <di:waypoint x="1235" y="500" />
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNShape id="ScriptTask_0h3fsja_di" bpmnElement="Task_1jyj2vs">
-        <dc:Bounds x="1010" y="460" width="100" height="80" />
+        <dc:Bounds x="1210" y="320" width="100" height="80" />
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape id="ScriptTask_12sydez_di" bpmnElement="ScriptTask_12sydez">
         <dc:Bounds x="860" y="140" width="100" height="80" />
@@ -420,10 +342,87 @@ dcso.preNSIRequest(execution)</bpmn:script>
         <di:waypoint x="178" y="500" />
         <di:waypoint x="210" y="500" />
       </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="ScriptTask_0h3fsja_di" bpmnElement="Task_1jyj2vs">
+        <dc:Bounds x="1010" y="460" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ParallelGateway_06a2n9u_di" bpmnElement="ParallelGateway_06a2n9u">
+        <dc:Bounds x="905" y="475" width="50" height="50" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_1tr3i9d_di" bpmnElement="SequenceFlow_1tr3i9d">
+        <di:waypoint x="955" y="500" />
+        <di:waypoint x="1010" y="500" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0aasemn_di" bpmnElement="SequenceFlow_0aasemn">
+        <di:waypoint x="840" y="620" />
+        <di:waypoint x="930" y="620" />
+        <di:waypoint x="930" y="525" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_103oxyw_di" bpmnElement="SequenceFlow_103oxyw">
+        <di:waypoint x="840" y="500" />
+        <di:waypoint x="905" y="500" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_14rhmx9_di" bpmnElement="SequenceFlow_14rhmx9">
+        <di:waypoint x="840" y="360" />
+        <di:waypoint x="930" y="360" />
+        <di:waypoint x="930" y="475" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="ParallelGateway_05zg916_di" bpmnElement="ParallelGateway_05zg916">
+        <dc:Bounds x="635" y="475" width="50" height="50" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_0il5j01_di" bpmnElement="SequenceFlow_0il5j01">
+        <di:waypoint x="660" y="525" />
+        <di:waypoint x="660" y="620" />
+        <di:waypoint x="740" y="620" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0euwvgf_di" bpmnElement="SequenceFlow_0euwvgf">
+        <di:waypoint x="685" y="500" />
+        <di:waypoint x="740" y="500" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_05250mp_di" bpmnElement="SequenceFlow_05250mp">
+        <di:waypoint x="660" y="475" />
+        <di:waypoint x="660" y="360" />
+        <di:waypoint x="740" y="360" />
+      </bpmndi:BPMNEdge>
       <bpmndi:BPMNEdge id="SequenceFlow_1h3kdce_di" bpmnElement="SequenceFlow_1h3kdce">
         <di:waypoint x="590" y="500" />
         <di:waypoint x="635" y="500" />
       </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1tqg26p_di" bpmnElement="SequenceFlow_1tqg26p">
+        <di:waypoint x="1410" y="360" />
+        <di:waypoint x="1310" y="360" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1tey3hz_di" bpmnElement="SequenceFlow_1tey3hz">
+        <di:waypoint x="1110" y="500" />
+        <di:waypoint x="1235" y="500" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0abqxa1_di" bpmnElement="SequenceFlow_0abqxa1">
+        <di:waypoint x="1460" y="460" />
+        <di:waypoint x="1460" y="400" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="ExclusiveGateway_0b52m39_di" bpmnElement="ExclusiveGateway_0b52m39" isMarkerVisible="true">
+        <dc:Bounds x="1235" y="475" width="50" height="50" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1218" y="463" width="85" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_126j77n_di" bpmnElement="SequenceFlow_126j77n">
+        <di:waypoint x="1285" y="500" />
+        <di:waypoint x="1410" y="500" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1339" y="482" width="17" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="EndEvent_0p0cjhl_di" bpmnElement="EndEvent_0p0cjhl">
+        <dc:Bounds x="1242" y="632" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_1nrfy6i_di" bpmnElement="SequenceFlow_1nrfy6i">
+        <di:waypoint x="1260" y="525" />
+        <di:waypoint x="1260" y="632" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1ezi1oi_di" bpmnElement="SequenceFlow_1ezi1oi">
+        <di:waypoint x="1260" y="400" />
+        <di:waypoint x="1260" y="475" />
+      </bpmndi:BPMNEdge>
     </bpmndi:BPMNPlane>
   </bpmndi:BPMNDiagram>
 </bpmn:definitions>
index b554994..9ac3579 100644 (file)
@@ -85,6 +85,11 @@ public class AAICreateTasks {
     private static String CONTRAIL_NETWORK_POLICY_FQDN_LIST = "contrailNetworkPolicyFqdnList";
     private static String HEAT_STACK_ID = "heatStackId";
     private static String NETWORK_POLICY_FQDN_PARAM = "network-policy-fqdn";
+    protected static final String EXCEPTION_NAME_EXISTS_WITH_DIFFERENT_ID =
+            "Exception in AAICreateOwningEntity. Can't create OwningEntity as name already exists in AAI associated with a different owning-entity-id (name must be unique)";
+    protected static final String EXCEPTION_NAME_AND_ID_ARE_NULL =
+            "Exception in AAICreateOwningEntity. OwningEntityId and Name are null.";
+
     @Autowired
     private AAIServiceInstanceResources aaiSIResources;
     @Autowired
@@ -192,9 +197,8 @@ public class AAICreateTasks {
             OwningEntity owningEntity = serviceInstance.getOwningEntity();
             if (Strings.isNullOrEmpty(owningEntity.getOwningEntityId())
                     && Strings.isNullOrEmpty(owningEntity.getOwningEntityName())) {
-                String msg = "Exception in AAICreateOwningEntity. OwningEntityId and Name are null.";
-                execution.setVariable("ErrorCreateOEAAI", msg);
-                exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
+                execution.setVariable("ErrorCreateOEAAI", EXCEPTION_NAME_AND_ID_ARE_NULL);
+                exceptionUtil.buildAndThrowWorkflowException(execution, 7000, "EXCEPTION_NAME_AND_ID_ARE_NULL");
             } else if (Strings.isNullOrEmpty(owningEntity.getOwningEntityId())
                     && !Strings.isNullOrEmpty(owningEntity.getOwningEntityName())) {
                 if (aaiSIResources.existsOwningEntityName(owningEntity.getOwningEntityName())) {
@@ -219,11 +223,11 @@ public class AAICreateTasks {
                         exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
                     } else {
                         if (aaiSIResources.existsOwningEntityName(owningEntity.getOwningEntityName())) {
-                            String msg =
-                                    "Exception in AAICreateOwningEntity. Can't create OwningEntity as name already exists in AAI associated with a different owning-entity-id (name must be unique)";
-                            logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), msg,
-                                    "BPMN", ErrorCode.UnknownError.getValue(), msg);
-                            exceptionUtil.buildAndThrowWorkflowException(execution, 7000, msg);
+                            logger.error(LoggingAnchor.FIVE, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
+                                    EXCEPTION_NAME_EXISTS_WITH_DIFFERENT_ID, "BPMN", ErrorCode.UnknownError.getValue(),
+                                    EXCEPTION_NAME_EXISTS_WITH_DIFFERENT_ID);
+                            exceptionUtil.buildAndThrowWorkflowException(execution, 7000,
+                                    EXCEPTION_NAME_EXISTS_WITH_DIFFERENT_ID);
                         } else {
                             aaiSIResources.createOwningEntityandConnectServiceInstance(owningEntity, serviceInstance);
                         }
index c21b467..a556d30 100644 (file)
@@ -1,19 +1,16 @@
 package org.onap.so.bpmn.infrastructure.adapter.cnf.tasks;
 
-import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
 import org.camunda.bpm.engine.delegate.DelegateExecution;
-import org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowAction;
 import org.onap.so.client.adapter.cnf.CnfAdapterClient;
-import org.onap.so.client.adapter.cnf.CnfAdapterClientException;
 import org.onap.so.client.adapter.cnf.entities.InstanceRequest;
 import org.onap.so.client.adapter.cnf.entities.InstanceResponse;
+import org.onap.so.client.adapter.cnf.entities.Labels;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
 
 @Component
 public class CnfAdapter {
@@ -25,8 +22,19 @@ public class CnfAdapter {
 
     public void callCnfAdapter(DelegateExecution execution) throws Exception {
         try {
-            final String instanceRequest = (String) execution.getVariable("instanceRequest");
-            InstanceRequest request = new ObjectMapper().readValue(instanceRequest, InstanceRequest.class);
+            InstanceRequest request = new InstanceRequest();
+            request.setRbName("test-rbdef");
+            request.setRbVersion("v1");
+            request.setCloudRegion("krd");
+            request.setVfModuleUUID("VF module UUID");
+            request.setProfileName("p1");
+            Map<String, String> overrideValues = new HashMap<>();
+            overrideValues.put("image.tag", "latest");
+            overrideValues.put("dcae_collector_ip", "1.2.3.4");
+            Map<String, String> labels = new HashMap<String, String>();
+            labels.put("custom-label-1", "abcdef");
+            request.setLabels(labels);
+            request.setOverrideValues(overrideValues);
             InstanceResponse response = cnfAdapterClient.createVfModule(request);
         } catch (Exception ex) {
             logger.error("Exception in callCnfAdapter", ex);
index 93d3051..7624bcb 100644 (file)
@@ -112,7 +112,7 @@ public class CnfAdapterCreateTasks {
         request.setRbName(vfModule.getModelInfoVfModule().getModelInvariantUUID());
         request.setRbVersion(vfModule.getModelInfoVfModule().getModelUUID());
         request.setCloudRegion(cloudRegion.getLcpCloudRegionId());
-        request.setReleaseName(vfModule.getVfModuleId());
+        request.setVfModuleUUID(vfModule.getVfModuleId());
         request.setProfileName(sdncDirectives.get("k8s-rb-profile-name"));
         request.setOverrideValues(sdncDirectives);
         return request;
index a1e513f..3b81d52 100644 (file)
@@ -22,17 +22,22 @@ import org.onap.so.bpmn.infrastructure.decisionpoint.api.ControllerRunnable;
 import org.onap.so.bpmn.servicedecomposition.bbobjects.Pnf;
 import org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance;
 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
+import org.onap.so.bpmn.servicedecomposition.entities.GeneralBuildingBlock;
 import org.onap.so.bpmn.servicedecomposition.entities.ResourceKey;
 import org.onap.so.bpmn.servicedecomposition.tasks.ExtractPojosForBB;
 import org.onap.so.client.cds.AbstractCDSProcessingBBUtils;
+import org.onap.so.client.cds.ConfigureInstanceParamsForPnf;
 import org.onap.so.client.cds.beans.AbstractCDSPropertiesBean;
 import org.onap.so.client.cds.PayloadConstants;
 import org.onap.so.client.exception.BBObjectNotFoundException;
 import org.onap.so.client.exception.ExceptionBuilder;
+import org.onap.so.client.exception.PayloadGenerationException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 import static org.onap.so.client.cds.PayloadConstants.PRC_BLUEPRINT_NAME;
 import static org.onap.so.client.cds.PayloadConstants.PRC_BLUEPRINT_VERSION;
@@ -54,13 +59,16 @@ public class GenericPnfCDSControllerRunnableBB implements ControllerRunnable<Bui
     private AbstractCDSProcessingBBUtils abstractCDSProcessingBBUtils;
     private ExtractPojosForBB extractPojosForBB;
     private ExceptionBuilder exceptionBuilder;
+    private ConfigureInstanceParamsForPnf configureInstanceParamsForPnf;
 
     @Autowired
     public GenericPnfCDSControllerRunnableBB(AbstractCDSProcessingBBUtils abstractCDSProcessingBBUtils,
-            ExtractPojosForBB extractPojosForBB, ExceptionBuilder exceptionBuilder) {
+            ExtractPojosForBB extractPojosForBB, ExceptionBuilder exceptionBuilder,
+            ConfigureInstanceParamsForPnf configureInstanceParamsForPnf) {
         this.abstractCDSProcessingBBUtils = abstractCDSProcessingBBUtils;
         this.extractPojosForBB = extractPojosForBB;
         this.exceptionBuilder = exceptionBuilder;
+        this.configureInstanceParamsForPnf = configureInstanceParamsForPnf;
     }
 
     @Override
@@ -115,6 +123,7 @@ public class GenericPnfCDSControllerRunnableBB implements ControllerRunnable<Bui
         String resolutionKey = null;
         try {
             final Pnf pnf = getPnf(execution);
+            final String modelCustomizationUuid = pnf.getModelInfoPnf().getModelCustomizationUuid();
             final ServiceInstance serviceInstance = getServiceInstance(execution);
             resolutionKey = pnf.getPnfName();
 
@@ -123,10 +132,17 @@ public class GenericPnfCDSControllerRunnableBB implements ControllerRunnable<Bui
                     pnfObject);
             setExecutionVariable("pnf-id", pnf.getPnfId(), pnfObject);
             setExecutionVariable("pnf-name", resolutionKey, pnfObject);
-            setExecutionVariable("pnf-customization-uuid", pnf.getModelInfoPnf().getModelCustomizationUuid(),
-                    pnfObject);
+            setExecutionVariable("pnf-customization-uuid", modelCustomizationUuid, pnfObject);
+
+            final GeneralBuildingBlock generalBuildingBlock = execution.getGeneralBuildingBlock();
 
-        } catch (BBObjectNotFoundException exception) {
+            List<Map<String, Object>> userParamsFromRequest =
+                    generalBuildingBlock.getRequestContext().getRequestParameters().getUserParams();
+            if (userParamsFromRequest != null && userParamsFromRequest.size() != 0) {
+                configureInstanceParamsForPnf.populateInstanceParams(pnfObject, userParamsFromRequest,
+                        modelCustomizationUuid);
+            }
+        } catch (BBObjectNotFoundException | PayloadGenerationException exception) {
             logger.error("An exception occurred when creating payload for CDS request", exception);
             exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, exception);
         }
index f44c15a..b74aa90 100644 (file)
@@ -34,6 +34,7 @@ import org.springframework.core.env.Environment;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.retry.annotation.Backoff;
 import org.springframework.retry.annotation.Retryable;
@@ -75,11 +76,32 @@ public class CnfAdapterClient {
         }
     }
 
+    @Retryable(value = {HttpServerErrorException.class}, maxAttempts = 3, backoff = @Backoff(delay = 3000))
+    public InstanceResponse healthcheck() throws CnfAdapterClientException {
+        try {
+            // String uri = env.getRequiredProperty("mso.cnf.adapter.endpoint"); //TODO: This needs to be added as well
+            // for configuration
+            String uri = "https://localhost:32780"; // TODO: What is the correct uri?
+            String endpoint = UriBuilder.fromUri(uri).path("/api/cnf-adapter/v1/healthcheck").build().toString();
+            HttpEntity<?> entity = new HttpEntity<>(getHttpHeaders());
+            ResponseEntity<InstanceResponse> result =
+                    restTemplate.exchange(endpoint, HttpMethod.GET, entity, InstanceResponse.class);
+            return result.getBody();
+        } catch (HttpClientErrorException e) {
+            logger.error("Error Calling CNF Adapter, e");
+            if (HttpStatus.SC_NOT_FOUND == e.getStatusCode().value()) {
+                throw new EntityNotFoundException(e.getResponseBodyAsString());
+            }
+            throw e;
+        }
+    }
+
     protected HttpHeaders getHttpHeaders() {
         HttpHeaders headers = new HttpHeaders();
-        List<org.springframework.http.MediaType> acceptableMediaTypes = new ArrayList<>();
-        acceptableMediaTypes.add(org.springframework.http.MediaType.APPLICATION_JSON);
+        List<MediaType> acceptableMediaTypes = new ArrayList<>();
+        acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
         headers.setAccept(acceptableMediaTypes);
+        headers.setContentType(MediaType.APPLICATION_JSON);
         /*
          * try { String userCredentials = CryptoUtils.decrypt(env.getRequiredProperty("mso.cnf.adapter.auth"),
          * env.getRequiredProperty("mso.msoKey")); if (userCredentials != null) { headers.add(HttpHeaders.AUTHORIZATION,
index e405809..37d4e41 100644 (file)
@@ -11,18 +11,18 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
         "override-values"})
 public class InstanceRequest {
 
-    @JsonProperty("rb-name")
+    @JsonProperty("modelInvariantId")
     private String rbName;
-    @JsonProperty("rb-version")
+    @JsonProperty("modelVersionId")
     private String rbVersion;
-    @JsonProperty("profile-name")
+    @JsonProperty("k8sRBProfileName")
     private String profileName;
-    @JsonProperty("release-name")
-    private String releaseName;
-    @JsonProperty("cloud-region")
+    @JsonProperty("vfModuleUUID")
+    private String vfModuleUUID;
+    @JsonProperty("cloudRegionId")
     private String cloudRegion;
     @JsonProperty("labels")
-    private Labels labels;
+    private Map<String, String> labels;
     @JsonProperty(value = "override-values")
     private Map<String, String> overrideValues;
 
@@ -67,21 +67,21 @@ public class InstanceRequest {
     }
 
     @JsonProperty("labels")
-    public Labels getLabels() {
+    public Map<String, String> getLabels() {
         return labels;
     }
 
     @JsonProperty("labels")
-    public void setLabels(Labels labels) {
+    public void setLabels(Map<String, String> labels) {
         this.labels = labels;
     }
 
-    public String getReleaseName() {
-        return releaseName;
+    public String getVfModuleUUID() {
+        return vfModuleUUID;
     }
 
-    public void setReleaseName(String releaseName) {
-        this.releaseName = releaseName;
+    public void setVfModuleUUID(String vfModuleUUID) {
+        this.vfModuleUUID = vfModuleUUID;
     }
 
     public Map<String, String> getOverrideValues() {
index f09e792..e1d3a7c 100644 (file)
@@ -9,9 +9,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -37,6 +37,7 @@ import java.util.List;
 import java.util.Optional;
 import java.util.TreeSet;
 import java.util.stream.Collectors;
+import com.google.common.base.Strings;
 import org.camunda.bpm.engine.delegate.BpmnError;
 import org.junit.Before;
 import org.junit.Rule;
@@ -302,6 +303,22 @@ public class AAICreateTasksTest extends BaseTaskTest {
                 .createOwningEntityandConnectServiceInstance(serviceInstance.getOwningEntity(), serviceInstance);
     }
 
+    @Test
+    public void createOwningEntityShouldThrowExceptionWhenNameAndIDAreNull() {
+        boolean catchedBpmnError = false;
+        serviceInstance.getOwningEntity().setOwningEntityName(null);
+        serviceInstance.getOwningEntity().setOwningEntityId(null);
+
+        try {
+            aaiCreateTasks.createOwningEntity(execution);
+        } catch (BpmnError err) {
+            catchedBpmnError = true;
+        }
+
+        assertTrue(catchedBpmnError);
+        assertEquals(execution.getVariable("ErrorCreateOEAAI"), aaiCreateTasks.EXCEPTION_NAME_AND_ID_ARE_NULL);
+    }
+
     @Test
     public void createOwningEntityNullOwningEntityNameTest() throws Exception {
         expectedException.expect(BpmnError.class);
index d6a28cb..1cba35d 100644 (file)
@@ -29,16 +29,31 @@ import org.onap.so.bpmn.servicedecomposition.bbobjects.Pnf;
 import org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance;
 import org.onap.so.bpmn.servicedecomposition.entities.BuildingBlock;
 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
+import org.onap.so.bpmn.servicedecomposition.entities.GeneralBuildingBlock;
 import org.onap.so.bpmn.servicedecomposition.entities.ResourceKey;
+import org.onap.so.bpmn.servicedecomposition.generalobjects.RequestContext;
+import org.onap.so.bpmn.servicedecomposition.generalobjects.RequestParameters;
 import org.onap.so.bpmn.servicedecomposition.modelinfo.ModelInfoPnf;
 import org.onap.so.bpmn.servicedecomposition.modelinfo.ModelInfoServiceInstance;
 import org.onap.so.bpmn.servicedecomposition.tasks.ExtractPojosForBB;
+import org.onap.so.client.cds.ConfigureInstanceParamsForPnf;
 import org.onap.so.client.cds.beans.AbstractCDSPropertiesBean;
 import org.onap.so.client.exception.BBObjectNotFoundException;
+import org.onap.so.client.exception.PayloadGenerationException;
+import org.onap.so.serviceinstancebeans.Service;
+import org.onap.so.serviceinstancebeans.Pnfs;
+import org.onap.so.serviceinstancebeans.Resources;
+import org.onap.so.serviceinstancebeans.ModelInfo;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.when;
 import static org.onap.so.bpmn.infrastructure.pnf.delegate.ExecutionVariableNames.EXECUTION_OBJECT;
 import static org.onap.so.bpmn.infrastructure.pnf.delegate.ExecutionVariableNames.MSO_REQUEST_ID;
@@ -51,6 +66,8 @@ public class GenericPnfCDSControllerRunnableBBTest {
 
     @Mock
     private ExtractPojosForBB extractPojosForBB;
+    @Mock
+    private ConfigureInstanceParamsForPnf configureInstanceParamsForPnf;
 
     @InjectMocks
     private GenericPnfCDSControllerRunnableBB genericPnfCDSControllerRunnableBB;
@@ -67,6 +84,7 @@ public class GenericPnfCDSControllerRunnableBBTest {
     private final static String serviceModelUUID = "6bc0b04d-1873-4721-b53d-6615225b2a28";
     private final static String pnfCustomizationUUID = "9acb3a83-8a52-412c-9a45-901764938144";
     private final static String action = "action";
+    private static final String GENERAL_BLOCK_EXECUTION_MAP_KEY = "gBBInput";
 
     @Before
     public void setUp() {
@@ -104,7 +122,7 @@ public class GenericPnfCDSControllerRunnableBBTest {
     }
 
     @Test
-    public void prepareTest() throws BBObjectNotFoundException {
+    public void prepareTest() throws BBObjectNotFoundException, PayloadGenerationException {
         // given
         prepareData();
 
@@ -119,6 +137,7 @@ public class GenericPnfCDSControllerRunnableBBTest {
         assertThat(abstractCDSPropertiesBean).isNotNull();
         assertThat(abstractCDSPropertiesBean.getRequestObject()).isNotNull();
         assertThat(abstractCDSPropertiesBean.getRequestObject()).isInstanceOf(String.class);
+        assertThat(execution.getGeneralBuildingBlock()).isNotNull();
 
         assertEquals(blueprintName, abstractCDSPropertiesBean.getBlueprintName());
         assertEquals(blueprintVersion, abstractCDSPropertiesBean.getBlueprintVersion());
@@ -134,7 +153,7 @@ public class GenericPnfCDSControllerRunnableBBTest {
         assertEquals(pnfCustomizationUUID, actionProperties.get("pnf-customization-uuid"));
     }
 
-    private void prepareData() throws BBObjectNotFoundException {
+    private void prepareData() throws BBObjectNotFoundException, PayloadGenerationException {
         Pnf pnf = new Pnf();
         ServiceInstance serviceInstance = new ServiceInstance();
 
@@ -149,8 +168,62 @@ public class GenericPnfCDSControllerRunnableBBTest {
         modelInfoServiceInstance.setModelUuid(serviceModelUUID);
         serviceInstance.setModelInfoServiceInstance(modelInfoServiceInstance);
 
+        execution.setVariable(GENERAL_BLOCK_EXECUTION_MAP_KEY,
+                createGeneralBuildingBlock(createService(createPnfsList())));
         when(extractPojosForBB.extractByKey(eq(execution), eq(ResourceKey.PNF))).thenReturn(pnf);
         when(extractPojosForBB.extractByKey(eq(execution), eq(ResourceKey.SERVICE_INSTANCE_ID)))
                 .thenReturn(serviceInstance);
+        doNothing().when(configureInstanceParamsForPnf).populateInstanceParams(any(), any(), any());
+    }
+
+    private Service createService(List<Pnfs> pnfList) {
+        Service service = new Service();
+        Resources resources = new Resources();
+        resources.setPnfs(pnfList);
+        service.setResources(resources);
+        return service;
+    }
+
+    private GeneralBuildingBlock createGeneralBuildingBlock(Object serviceJson) {
+        GeneralBuildingBlock generalBuildingBlock = new GeneralBuildingBlock();
+        RequestContext requestContext = new RequestContext();
+        RequestParameters requestParameters = new RequestParameters();
+        requestParameters.setUserParams(createRequestUserParams(serviceJson));
+        requestContext.setRequestParameters(requestParameters);
+        generalBuildingBlock.setRequestContext(requestContext);
+        return generalBuildingBlock;
+    }
+
+    private List<Map<String, Object>> createRequestUserParams(Object serviceJson) {
+        List<Map<String, Object>> userParams = new ArrayList<>();
+        Map<String, Object> userParamMap = new HashMap<>();
+        userParamMap.put("service", serviceJson);
+        userParams.add(userParamMap);
+        return userParams;
+    }
+
+    private List<Pnfs> createPnfsList() {
+        List<Map<String, String>> instanceParamsListSearchedPnf = new ArrayList<>();
+        Map<String, String> instanceParam = new HashMap<>();
+        instanceParam.put("INSTANCE_PARAM1_NAME", "INSTANCE_PARAM1_VALUE");
+        instanceParam.put("INSTANCE_PARAM2_NAME", "INSTANCE_PARAM2_VALUE");
+        Map<String, String> instanceParam2 = new HashMap<>();
+        instanceParam2.put("INSTANCE_PARAM3_NAME", "INSTANCE_PARAM3_VALUE");
+        instanceParamsListSearchedPnf.add(instanceParam);
+        instanceParamsListSearchedPnf.add(instanceParam2);
+        Pnfs searchedPnf = createPnfs("0c1ac643-377e-475b-be50-6be65f91a7ad", instanceParamsListSearchedPnf);
+
+        List<Pnfs> pnfList = new ArrayList<>();
+        pnfList.add(searchedPnf);
+        return pnfList;
+    }
+
+    private Pnfs createPnfs(String pnfModelCustomizationId, List<Map<String, String>> instanceParamsList) {
+        Pnfs pnfs = new Pnfs();
+        ModelInfo modelInfo = new ModelInfo();
+        modelInfo.setModelCustomizationUuid(pnfModelCustomizationId);
+        pnfs.setModelInfo(modelInfo);
+        pnfs.setInstanceParams(instanceParamsList);
+        return pnfs;
     }
 }
index 83675da..e5eb3e0 100644 (file)
@@ -23,10 +23,12 @@ package org.onap.so.beans.nsmf;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.Data;
+import lombok.ToString;
 import java.util.List;
 
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @Data
+@ToString
 public class AnSliceProfile {
 
     @JsonProperty(value = "sliceProfileId", required = true)
index f0857fc..4aa5671 100644 (file)
@@ -22,11 +22,19 @@ package org.onap.so.beans.nsmf;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.gson.JsonObject;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
 import java.io.IOException;
 import java.io.Serializable;
 import java.util.HashMap;
 import java.util.Map;
 
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@ToString
 public class SliceTaskParams implements Serializable {
 
     private static final long serialVersionUID = -4389946152970978423L;
@@ -45,17 +53,17 @@ public class SliceTaskParams implements Serializable {
 
     private String cnScriptName;
 
-    private Map<String, Object> serviceProfile;
+    private Map<String, Object> serviceProfile = new HashMap<>();
 
     private String suggestNsiId;
 
     private String suggestNsiName;
 
-    private Map<String, Object> sliceProfileTn;
+    private Map<String, Object> sliceProfileTn = new HashMap<>();
 
-    private Map<String, Object> sliceProfileCn;
+    private Map<String, Object> sliceProfileCn = new HashMap<>();
 
-    private Map<String, Object> sliceProfileAn;
+    private Map<String, Object> sliceProfileAn = new HashMap<>();
 
     private String tnSuggestNssiId;
 
@@ -87,237 +95,6 @@ public class SliceTaskParams implements Serializable {
 
     private String anStatusDescription;
 
-    public SliceTaskParams() {
-        this.serviceProfile = new HashMap<>();
-        this.sliceProfileAn = new HashMap<>();
-        this.sliceProfileCn = new HashMap<>();
-        this.sliceProfileTn = new HashMap<>();
-    }
-
-    public String getNstId() {
-        return nstId;
-    }
-
-    public void setNstId(String nstId) {
-        this.nstId = nstId;
-    }
-
-    public String getNstName() {
-        return nstName;
-    }
-
-    public void setNstName(String nstName) {
-        this.nstName = nstName;
-    }
-
-    public String getTnScriptName() {
-        return tnScriptName;
-    }
-
-    public void setTnScriptName(String tnScriptName) {
-        this.tnScriptName = tnScriptName;
-    }
-
-    public String getAnScriptName() {
-        return anScriptName;
-    }
-
-    public void setAnScriptName(String anScriptName) {
-        this.anScriptName = anScriptName;
-    }
-
-    public String getCnScriptName() {
-        return cnScriptName;
-    }
-
-    public void setCnScriptName(String cnScriptName) {
-        this.cnScriptName = cnScriptName;
-    }
-
-    public String getServiceId() {
-        return serviceId;
-    }
-
-    public void setServiceId(String serviceId) {
-        this.serviceId = serviceId;
-    }
-
-    public String getServiceName() {
-        return serviceName;
-    }
-
-    public void setServiceName(String serviceName) {
-        this.serviceName = serviceName;
-    }
-
-    public Map<String, Object> getServiceProfile() {
-        return serviceProfile;
-    }
-
-    public void setServiceProfile(Map<String, Object> serviceProfile) {
-        this.serviceProfile = serviceProfile;
-    }
-
-    public String getSuggestNsiId() {
-        return suggestNsiId;
-    }
-
-    public void setSuggestNsiId(String suggestNsiId) {
-        this.suggestNsiId = suggestNsiId;
-    }
-
-    public String getSuggestNsiName() {
-        return suggestNsiName;
-    }
-
-    public void setSuggestNsiName(String suggestNsiName) {
-        this.suggestNsiName = suggestNsiName;
-    }
-
-    public Map<String, Object> getSliceProfileTn() {
-        return sliceProfileTn;
-    }
-
-    public void setSliceProfileTn(Map<String, Object> sliceProfileTn) {
-        this.sliceProfileTn = sliceProfileTn;
-    }
-
-    public Map<String, Object> getSliceProfileCn() {
-        return sliceProfileCn;
-    }
-
-    public void setSliceProfileCn(Map<String, Object> sliceProfileCn) {
-        this.sliceProfileCn = sliceProfileCn;
-    }
-
-    public Map<String, Object> getSliceProfileAn() {
-        return sliceProfileAn;
-    }
-
-    public void setSliceProfileAn(Map<String, Object> sliceProfileAn) {
-        this.sliceProfileAn = sliceProfileAn;
-    }
-
-    public String getTnSuggestNssiId() {
-        return tnSuggestNssiId;
-    }
-
-    public void setTnSuggestNssiId(String tnSuggestNssiId) {
-        this.tnSuggestNssiId = tnSuggestNssiId;
-    }
-
-    public String getTnSuggestNssiName() {
-        return tnSuggestNssiName;
-    }
-
-    public void setTnSuggestNssiName(String tnSuggestNssiName) {
-        this.tnSuggestNssiName = tnSuggestNssiName;
-    }
-
-    public String getTnProgress() {
-        return tnProgress;
-    }
-
-    public void setTnProgress(String tnProgress) {
-        this.tnProgress = tnProgress;
-    }
-
-    public String getTnStatus() {
-        return tnStatus;
-    }
-
-    public void setTnStatus(String tnStatus) {
-        this.tnStatus = tnStatus;
-    }
-
-    public String getTnStatusDescription() {
-        return tnStatusDescription;
-    }
-
-    public void setTnStatusDescription(String tnStatusDescription) {
-        this.tnStatusDescription = tnStatusDescription;
-    }
-
-    public String getCnSuggestNssiId() {
-        return cnSuggestNssiId;
-    }
-
-    public void setCnSuggestNssiId(String cnSuggestNssiId) {
-        this.cnSuggestNssiId = cnSuggestNssiId;
-    }
-
-    public String getCnSuggestNssiName() {
-        return cnSuggestNssiName;
-    }
-
-    public void setCnSuggestNssiName(String cnSuggestNssiName) {
-        this.cnSuggestNssiName = cnSuggestNssiName;
-    }
-
-    public String getCnProgress() {
-        return cnProgress;
-    }
-
-    public void setCnProgress(String cnProgress) {
-        this.cnProgress = cnProgress;
-    }
-
-    public String getCnStatus() {
-        return cnStatus;
-    }
-
-    public void setCnStatus(String cnStatus) {
-        this.cnStatus = cnStatus;
-    }
-
-    public String getCnStatusDescription() {
-        return cnStatusDescription;
-    }
-
-    public void setCnStatusDescription(String cnStatusDescription) {
-        this.cnStatusDescription = cnStatusDescription;
-    }
-
-    public String getAnSuggestNssiId() {
-        return anSuggestNssiId;
-    }
-
-    public void setAnSuggestNssiId(String anSuggestNssiId) {
-        this.anSuggestNssiId = anSuggestNssiId;
-    }
-
-    public String getAnSuggestNssiName() {
-        return anSuggestNssiName;
-    }
-
-    public void setAnSuggestNssiName(String anSuggestNssiName) {
-        this.anSuggestNssiName = anSuggestNssiName;
-    }
-
-    public String getAnProgress() {
-        return anProgress;
-    }
-
-    public void setAnProgress(String anProgress) {
-        this.anProgress = anProgress;
-    }
-
-    public String getAnStatus() {
-        return anStatus;
-    }
-
-    public void setAnStatus(String anStatus) {
-        this.anStatus = anStatus;
-    }
-
-    public String getAnStatusDescription() {
-        return anStatusDescription;
-    }
-
-    public void setAnStatusDescription(String anStatusDescription) {
-        this.anStatusDescription = anStatusDescription;
-    }
-
     public String convertToJson() {
         JsonObject jsonObject = new JsonObject();
         jsonObject.addProperty("ServiceId", serviceId);
index 87de04a..dd73fdb 100644 (file)
  */
 package org.onap.so.beans.nsmf;
 
-import lombok.Data;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.JsonObject;
+import lombok.*;
 import org.onap.so.beans.nsmf.oof.TemplateInfo;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
 import java.util.Map;
 
 
 @Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+@Builder
 public class SliceTaskParamsAdapter {
     private static final long serialVersionUID = -7785578865170503301L;
 
@@ -53,4 +63,196 @@ public class SliceTaskParamsAdapter {
     private SliceTaskInfo<CnSliceProfile> cnSliceTaskInfo;
 
     private SliceTaskInfo<AnSliceProfile> anSliceTaskInfo;
+
+    @SuppressWarnings("unchecked")
+    public void convertFromJson(String jsonString) throws IOException {
+        ObjectMapper mapper = new ObjectMapper();
+        Map<String, String> paramMap = (Map<String, String>) mapper.readValue(jsonString, Map.class);
+
+        this.setServiceName(paramMap.get("ServiceName"));
+        this.setServiceId(paramMap.get("ServiceId"));
+        this.setNstId(paramMap.get("NSTId"));
+        this.setNstName(paramMap.get("NSTName"));
+        this.setSuggestNsiId(paramMap.get("suggestNSIId"));
+        this.setSuggestNsiName(paramMap.get("suggestNSIName"));
+
+        this.setServiceProfile(replaceHeader(paramMap, "ServiceProfile."));
+
+        TnSliceProfile tnBHSliceProfile = mapper.readValue(
+                mapper.writeValueAsString(replaceHeader(paramMap, "SliceProfile.TN.BH.")), TnSliceProfile.class);
+        this.tnBHSliceTaskInfo.setSliceProfile(tnBHSliceProfile);
+
+        TnSliceProfile tnMHSliceProfile = mapper.readValue(
+                mapper.writeValueAsString(replaceHeader(paramMap, "SliceProfile.TN.MH.")), TnSliceProfile.class);
+        this.tnMHSliceTaskInfo.setSliceProfile(tnMHSliceProfile);
+
+        TnSliceProfile tnFHSliceProfile = mapper.readValue(
+                mapper.writeValueAsString(replaceHeader(paramMap, "SliceProfile.TN.FH.")), TnSliceProfile.class);
+        this.tnFHSliceTaskInfo.setSliceProfile(tnFHSliceProfile);
+
+        CnSliceProfile cnSliceProfile = mapper.readValue(
+                mapper.writeValueAsString(replaceHeader(paramMap, "SliceProfile.CN.")), CnSliceProfile.class);
+        this.cnSliceTaskInfo.setSliceProfile(cnSliceProfile);
+
+        AnSliceProfile anSliceProfile = mapper.readValue(
+                mapper.writeValueAsString(replaceHeader(paramMap, "SliceProfile.AN.")), AnSliceProfile.class);
+        this.anSliceTaskInfo.setSliceProfile(anSliceProfile);
+
+        this.tnBHSliceTaskInfo.setSuggestNssiId(paramMap.get("TN.BH.SuggestNSSIId"));
+        this.tnBHSliceTaskInfo.setSuggestNssiName(paramMap.get("TN.BH.SuggestNSSIName"));
+        this.tnBHSliceTaskInfo.setProgress(paramMap.get("TN.BH.progress"));
+        this.tnBHSliceTaskInfo.setStatus(paramMap.get("TN.BH.status"));
+        this.tnBHSliceTaskInfo.setStatusDescription(paramMap.get("TN.BH.statusDescription"));
+        this.tnBHSliceTaskInfo.setScriptName(paramMap.get("TN.BH.ScriptName"));
+
+        this.tnMHSliceTaskInfo.setSuggestNssiId(paramMap.get("TN.MH.SuggestNSSIId"));
+        this.tnMHSliceTaskInfo.setSuggestNssiName(paramMap.get("TN.MH.SuggestNSSIName"));
+        this.tnMHSliceTaskInfo.setProgress(paramMap.get("TN.MH.progress"));
+        this.tnMHSliceTaskInfo.setStatus(paramMap.get("TN.MH.status"));
+        this.tnMHSliceTaskInfo.setStatusDescription(paramMap.get("TN.MH.statusDescription"));
+        this.tnMHSliceTaskInfo.setScriptName(paramMap.get("TN.MH.ScriptName"));
+
+        this.tnFHSliceTaskInfo.setSuggestNssiId(paramMap.get("TN.FH.SuggestNSSIId"));
+        this.tnFHSliceTaskInfo.setSuggestNssiName(paramMap.get("TN.FH.SuggestNSSIName"));
+        this.tnFHSliceTaskInfo.setProgress(paramMap.get("TN.FH.progress"));
+        this.tnFHSliceTaskInfo.setStatus(paramMap.get("TN.FH.status"));
+        this.tnFHSliceTaskInfo.setStatusDescription(paramMap.get("TN.FH.statusDescription"));
+        this.tnFHSliceTaskInfo.setScriptName(paramMap.get("TN.FH.ScriptName"));
+
+        this.cnSliceTaskInfo.setSuggestNssiId(paramMap.get("CN.SuggestNSSIId"));
+        this.cnSliceTaskInfo.setSuggestNssiName(paramMap.get("CN.SuggestNSSIName"));
+        this.cnSliceTaskInfo.setProgress(paramMap.get("CN.progress"));
+        this.cnSliceTaskInfo.setStatus(paramMap.get("CN.status"));
+        this.cnSliceTaskInfo.setStatusDescription(paramMap.get("CN.statusDescription"));
+        this.cnSliceTaskInfo.setScriptName(paramMap.get("CN.ScriptName"));
+
+        this.anSliceTaskInfo.setSuggestNssiId(paramMap.get("AN.SuggestNSSIId"));
+        this.anSliceTaskInfo.setSuggestNssiName(paramMap.get("AN.SuggestNSSIName"));
+        this.anSliceTaskInfo.setProgress(paramMap.get("AN.progress"));
+        this.anSliceTaskInfo.setStatus(paramMap.get("AN.status"));
+        this.anSliceTaskInfo.setStatusDescription(paramMap.get("AN.statusDescription"));
+        this.anSliceTaskInfo.setScriptName(paramMap.get("AN.ScriptName"));
+    }
+
+    public String convertToJson() {
+        JsonObject jsonObject = new JsonObject();
+        jsonObject.addProperty("ServiceId", serviceId);
+        jsonObject.addProperty("ServiceName", serviceName);
+        jsonObject.addProperty("NSTId", nstId);
+        jsonObject.addProperty("NSTName", nstName);
+        jsonObject.addProperty("suggestNSIId", suggestNsiId);
+        jsonObject.addProperty("suggestNSIName", suggestNsiName);
+
+        for (Map.Entry<String, Object> entry : serviceProfile.entrySet()) {
+            jsonObject.addProperty("ServiceProfile." + entry.getKey(), entry.getValue().toString());
+        }
+
+        Map<String, Object> sliceProfileAn = bean2Map(anSliceTaskInfo.getSliceProfile());
+
+        for (Map.Entry<String, Object> entry : sliceProfileAn.entrySet()) {
+            jsonObject.addProperty("SliceProfile.AN." + entry.getKey(), entry.getValue().toString());
+        }
+
+        Map<String, Object> sliceProfileCn = bean2Map(cnSliceTaskInfo.getSliceProfile());
+        for (Map.Entry<String, Object> entry : sliceProfileCn.entrySet()) {
+            jsonObject.addProperty("SliceProfile.CN." + entry.getKey(), entry.getValue().toString());
+        }
+
+        Map<String, Object> sliceProfileTnBH = bean2Map(tnBHSliceTaskInfo.getSliceProfile());
+        for (Map.Entry<String, Object> entry : sliceProfileTnBH.entrySet()) {
+            jsonObject.addProperty("SliceProfile.TN.BH." + entry.getKey(), entry.getValue().toString());
+        }
+
+        Map<String, Object> sliceProfileTnMH = bean2Map(tnMHSliceTaskInfo.getSliceProfile());
+        for (Map.Entry<String, Object> entry : sliceProfileTnMH.entrySet()) {
+            jsonObject.addProperty("SliceProfile.TN.MH." + entry.getKey(), entry.getValue().toString());
+        }
+
+        Map<String, Object> sliceProfileTnFH = bean2Map(tnFHSliceTaskInfo.getSliceProfile());
+        for (Map.Entry<String, Object> entry : sliceProfileTnFH.entrySet()) {
+            jsonObject.addProperty("SliceProfile.TN.FH." + entry.getKey(), entry.getValue().toString());
+        }
+
+        jsonObject.addProperty("TN.BH.SuggestNSSIId", tnBHSliceTaskInfo.getSuggestNssiId());
+        jsonObject.addProperty("TN.BH.SuggestNSSIName", tnBHSliceTaskInfo.getSuggestNssiName());
+        jsonObject.addProperty("TN.BH.progress", tnBHSliceTaskInfo.getProgress());
+        jsonObject.addProperty("TN.BH.status", tnBHSliceTaskInfo.getStatus());
+        jsonObject.addProperty("TN.BH.statusDescription", tnBHSliceTaskInfo.getStatusDescription());
+        jsonObject.addProperty("TN.BH.ScriptName", tnBHSliceTaskInfo.getScriptName());
+
+
+        jsonObject.addProperty("TN.MH.SuggestNSSIId", tnMHSliceTaskInfo.getSuggestNssiId());
+        jsonObject.addProperty("TN.MH.SuggestNSSIName", tnMHSliceTaskInfo.getSuggestNssiName());
+        jsonObject.addProperty("TN.MH.progress", tnMHSliceTaskInfo.getProgress());
+        jsonObject.addProperty("TN.MH.status", tnMHSliceTaskInfo.getStatus());
+        jsonObject.addProperty("TN.MH.statusDescription", tnMHSliceTaskInfo.getStatusDescription());
+        jsonObject.addProperty("TN.MH.ScriptName", tnMHSliceTaskInfo.getScriptName());
+
+
+        jsonObject.addProperty("TN.FH.SuggestNSSIId", tnFHSliceTaskInfo.getSuggestNssiId());
+        jsonObject.addProperty("TN.FH.SuggestNSSIName", tnFHSliceTaskInfo.getSuggestNssiName());
+        jsonObject.addProperty("TN.FH.progress", tnFHSliceTaskInfo.getProgress());
+        jsonObject.addProperty("TN.FH.status", tnFHSliceTaskInfo.getStatus());
+        jsonObject.addProperty("TN.FH.statusDescription", tnFHSliceTaskInfo.getStatusDescription());
+        jsonObject.addProperty("TN.FH.ScriptName", tnFHSliceTaskInfo.getScriptName());
+
+
+        jsonObject.addProperty("CN.SuggestNSSIId", cnSliceTaskInfo.getSuggestNssiId());
+        jsonObject.addProperty("CN.SuggestNSSIName", cnSliceTaskInfo.getSuggestNssiName());
+        jsonObject.addProperty("CN.progress", cnSliceTaskInfo.getProgress());
+        jsonObject.addProperty("CN.status", cnSliceTaskInfo.getStatus());
+        jsonObject.addProperty("CN.statusDescription", cnSliceTaskInfo.getStatusDescription());
+        jsonObject.addProperty("CN.ScriptName", cnSliceTaskInfo.getScriptName());
+
+
+        jsonObject.addProperty("AN.SuggestNSSIId", anSliceTaskInfo.getSuggestNssiId());
+        jsonObject.addProperty("AN.SuggestNSSIName", anSliceTaskInfo.getSuggestNssiName());
+        jsonObject.addProperty("AN.progress", anSliceTaskInfo.getProgress());
+        jsonObject.addProperty("AN.status", anSliceTaskInfo.getStatus());
+        jsonObject.addProperty("AN.statusDescription", anSliceTaskInfo.getStatusDescription());
+        jsonObject.addProperty("AN.ScriptName", anSliceTaskInfo.getScriptName());
+
+        return jsonObject.toString();
+    }
+
+    /**
+     * change T t to {@link Map}
+     * 
+     * @param t input
+     * @param <T> Object
+     * @return {@link Map}
+     */
+    private <T> Map<String, Object> bean2Map(T t) {
+        Map<String, Object> resMap = new HashMap<>();
+        try {
+            Field[] fields = t.getClass().getDeclaredFields();
+            for (Field field : fields) {
+                String name = field.getName();
+                Method method = t.getClass().getMethod("get" + name);
+                Object value = method.invoke(t);
+                resMap.put(name, value);
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return resMap;
+    }
+
+    /**
+     * replace of slice profile
+     * 
+     * @param paramMap params map
+     * @param header starts of key
+     * @return Map
+     */
+    private Map<String, Object> replaceHeader(Map<String, String> paramMap, String header) {
+        Map<String, Object> sliceProfileMap = new HashMap<>();
+        for (Map.Entry<String, String> entry : paramMap.entrySet()) {
+            if (entry.getKey().startsWith(header)) {
+                sliceProfileMap.put(entry.getKey().replaceFirst("^" + header, ""), entry.getValue());
+            }
+        }
+        return sliceProfileMap;
+    }
 }
index 7cfb60c..96c5b34 100644 (file)
  */
 package org.onap.so.beans.nsmf.oof;
 
-import lombok.Data;
-import org.onap.so.beans.nsmf.ServiceProfile;
+import lombok.*;
 import java.io.Serializable;
-import java.util.Map;
 
 @Data
-public class NssiReqBody implements Serializable {
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+@Builder
+public class NssiReqBody<T> implements Serializable {
 
     private static final long serialVersionUID = -76327522074333341L;
 
-    private Map<String, Object> serviceProfile;
+    private T sliceProfile;
 
     private RequestInfo requestInfo;
 
index e90391d..fd51b1a 100644 (file)
@@ -31,7 +31,6 @@ public class CamundaVariableNameConstants {
     public static final String GLOBAL_CUSTOMER_ID_PARAM_NAME = "globalCustomerId";
     public static final String SERVICE_TYPE_PARAM_NAME = "serviceType";
 
-
     public static final String NS_PACKAGE_MODEL_PARAM_NAME = "NSPackageModel";
     public static final String CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME =
             "CreateNsWorkflowProcessingException";
@@ -47,6 +46,11 @@ public class CamundaVariableNameConstants {
     public static final String CREATE_VNF_RESPONSE_PARAM_NAME = "createVnfResponse";
     public static final String OPERATION_STATUS_PARAM_NAME = "operationStatus";
 
+    public static final String TERMINATE_NS_REQUEST_PARAM_NAME = "terminateNsRequest";
+    public static final String NFVO_NF_INST_IDS_PARAM_NAME = "nfvoNfInstIds";
+    public static final String DELETE_VNF_RESPONSE_PARAM_NAME = "deleteVnfResponse";
+    public static final String TERMINATE_VNF_VNFID_PARAM_NAME = "vnfId";
+
     private CamundaVariableNameConstants() {}
 
 }
index a2128fc..14a4f43 100644 (file)
@@ -29,6 +29,7 @@ public class Constants {
     public static final String NS_WORKFLOW_ENGINE = "NS-WORKFLOW-ENGINE";
     public static final String CREATE_NS_WORKFLOW_NAME = "CreateNs";
     public static final String INSTANTIATE_NS_WORKFLOW_NAME = "InstantiateNs";
+    public static final String TERMINATE_NS_WORKFLOW_NAME = "TerminateNs";
     public static final String GET_NS_OCCURRENCE_OPERATION_STATUS_NAME = "GetNsOccurrenceOperationStatus";
 
 
index c48d10b..0da53a0 100644 (file)
@@ -22,6 +22,7 @@ package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai;
 import java.util.Optional;
 import org.onap.aai.domain.yang.GenericVnf;
 import org.onap.aai.domain.yang.ServiceInstance;
+import org.onap.aaiclient.client.aai.AAIObjectType;
 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
@@ -84,4 +85,12 @@ public class AaiServiceProviderImpl implements AaiServiceProvider {
         return aaiClientProvider.getAaiClient().get(GenericVnf.class,
                 AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId)));
     }
+
+    @Override
+    public void deleteGenericVnf(final String vnfId) {
+        logger.info("Deleting GenericVnf with id: {} from AAI.", vnfId);
+        final AAIResourceUri aaiResourceUri =
+                AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId));
+        aaiClientProvider.getAaiClient().delete(aaiResourceUri);
+    }
 }
index c053ba9..4f98e2c 100644 (file)
@@ -23,6 +23,7 @@ package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm;
 import java.util.Optional;
 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfRequest;
 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.DeleteVnfResponse;
 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse;
 
 public interface Sol003AdapterServiceProvider {
@@ -31,4 +32,6 @@ public interface Sol003AdapterServiceProvider {
 
     Optional<QueryJobResponse> getInstantiateOperationJobStatus(final String jobId);
 
+    Optional<DeleteVnfResponse> invokeTerminationRequest(final String vnfId);
+
 }
index 09fecc6..a0798f6 100644 (file)
@@ -24,6 +24,7 @@ import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003Adap
 import java.util.Optional;
 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfRequest;
 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.DeleteVnfResponse;
 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse;
 import org.onap.so.rest.exceptions.HttpResouceNotFoundException;
 import org.onap.so.rest.exceptions.InvalidRestRequestException;
@@ -114,4 +115,35 @@ public class Sol003AdapterServiceProviderImpl implements Sol003AdapterServicePro
             throw exception;
         }
     }
+
+    @Override
+    public Optional<DeleteVnfResponse> invokeTerminationRequest(final String vnfId) {
+        try {
+            final String url = urlProvider.getTerminateVnfUrl(vnfId);
+
+            final ResponseEntity<DeleteVnfResponse> response =
+                    httpServiceProvider.deleteHttpRequest(url, DeleteVnfResponse.class);
+            final HttpStatus httpStatus = response.getStatusCode();
+            if (!(httpStatus.equals(HttpStatus.ACCEPTED)) && !(httpStatus.equals(HttpStatus.OK))) {
+                LOGGER.error("Unable to invoke HTTP DELETE using URL: {}, Response Code: {}", url, httpStatus.value());
+                return Optional.empty();
+            }
+            if (!response.hasBody()) {
+                LOGGER.error(RECEIVED_RESPONSE_WITHOUT_BODY, response);
+                return Optional.empty();
+            }
+
+            final DeleteVnfResponse deleteVnfResponse = response.getBody();
+            if (deleteVnfResponse.getJobId() == null || deleteVnfResponse.getJobId().isEmpty()) {
+                LOGGER.error("Received invalid terminate response: {}", response);
+                return Optional.empty();
+            }
+
+            return Optional.of(deleteVnfResponse);
+        } catch (final RestProcessingException | InvalidRestRequestException
+                | HttpResouceNotFoundException httpInvocationException) {
+            LOGGER.error("Unexpected error while processing terminate request", httpInvocationException);
+            return Optional.empty();
+        }
+    }
 }
index 351d4bf..e3abc05 100644 (file)
@@ -61,4 +61,14 @@ public class Sol003AdapterUrlProvider {
         return UriComponentsBuilder.fromUri(baseUri).pathSegment("jobs").pathSegment(jobId).build().toString();
     }
 
+    /**
+     * Get VNFM terminate vnf URL
+     *
+     * @param vnfId
+     * @return
+     */
+    public String getTerminateVnfUrl(final String vnfId) {
+        return UriComponentsBuilder.fromUri(baseUri).pathSegment("vnfs").pathSegment(vnfId).build().toString();
+    }
+
 }
index 13cdc60..31e3011 100644 (file)
@@ -26,9 +26,12 @@ import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstan
 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME;
 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OCC_ID_PARAM_NAME;
 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.SERVICE_TYPE_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.TERMINATE_NS_REQUEST_PARAM_NAME;
 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.CREATE_NS_WORKFLOW_NAME;
 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.INSTANTIATE_NS_WORKFLOW_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.Constants.TERMINATE_NS_WORKFLOW_NAME;
 import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobAction.INSTANTIATE;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobAction.TERMINATE;
 import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.ERROR;
 import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED;
 import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED_WITH_ERROR;
@@ -47,14 +50,17 @@ import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.NsRequestProcessingExc
 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobAction;
 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum;
 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc;
 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpType;
 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.OperationStateEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
 import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
 import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest;
 import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
 import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest;
 import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance;
+import org.onap.so.etsi.nfvo.ns.lcm.model.TerminateNsRequest;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -156,8 +162,8 @@ public class JobExecutorService {
         final LocalDateTime currentDateTime = LocalDateTime.now();
         final NsLcmOpOcc newNsLcmOpOcc = new NsLcmOpOcc().id(nsInstanceId).operation(NsLcmOpType.INSTANTIATE)
                 .operationState(OperationStateEnum.PROCESSING).stateEnteredTime(currentDateTime)
-                .startTime(currentDateTime).isAutoInnovation(false).isCancelPending(false)
-                .operationParams(gson.toJson(instantiateNsRequest));
+                .startTime(currentDateTime).nfvoNsInst(getNfvoNsInst(nsInstanceId)).isAutoInnovation(false)
+                .isCancelPending(false).operationParams(gson.toJson(instantiateNsRequest));
         databaseServiceProvider.addNSLcmOpOcc(newNsLcmOpOcc);
         logger.info("New NSLcmOpOcc created in database :\n{}", newNsLcmOpOcc);
 
@@ -190,6 +196,89 @@ public class JobExecutorService {
         throw new NsRequestProcessingException(message);
     }
 
+    public String runTerminateNsJob(final String nsInstanceId, final TerminateNsRequest terminateNsRequest) {
+        doInitialTerminateChecks(nsInstanceId, terminateNsRequest);
+
+        final NfvoJob nfvoJob = new NfvoJob().startTime(LocalDateTime.now()).jobType("NS").jobAction(TERMINATE)
+                .resourceId(nsInstanceId).status(STARTING).progress(0);
+        databaseServiceProvider.addJob(nfvoJob);
+        logger.info("New job created in database :\n{}", nfvoJob);
+
+        final LocalDateTime currentDateTime = LocalDateTime.now();
+        final NsLcmOpOcc nsLcmOpOcc = new NsLcmOpOcc().id(nsInstanceId).operation(NsLcmOpType.TERMINATE)
+                .operationState(OperationStateEnum.PROCESSING).stateEnteredTime(currentDateTime)
+                .startTime(currentDateTime).nfvoNsInst(getNfvoNsInst(nsInstanceId)).isAutoInnovation(false)
+                .isCancelPending(false).operationParams(gson.toJson(terminateNsRequest));
+        databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc);
+        logger.info("New NSLcmOpOcc created in database :\n{}", nsLcmOpOcc);
+
+        workflowExecutorService.executeWorkflow(nfvoJob.getJobId(), TERMINATE_NS_WORKFLOW_NAME,
+                getVariables(nsInstanceId, nfvoJob.getJobId(), nsLcmOpOcc.getId(), terminateNsRequest));
+
+        final ImmutableSet<JobStatusEnum> jobFinishedStates =
+                ImmutableSet.of(FINISHED, ERROR, FINISHED_WITH_ERROR, IN_PROGRESS);
+        final ImmutablePair<String, JobStatusEnum> immutablePair =
+                waitForJobToFinish(nfvoJob.getJobId(), jobFinishedStates);
+
+        if (immutablePair.getRight() == null) {
+            final String message =
+                    "Failed to Terminate NS with id: " + nsInstanceId + " for request: \n" + terminateNsRequest;
+            logger.error(message);
+            throw new NsRequestProcessingException(message);
+        }
+
+        final JobStatusEnum finalJobStatus = immutablePair.getRight();
+
+        if (IN_PROGRESS.equals(finalJobStatus) || FINISHED.equals(finalJobStatus)) {
+            logger.info("Termination Job status: {}", finalJobStatus);
+            return nsLcmOpOcc.getId();
+        }
+
+        final String message = "Received unexpected Job Status: " + finalJobStatus + " Failed to Terminate NS with id: "
+                + nsInstanceId + " for request: \n" + terminateNsRequest;
+        logger.error(message);
+        throw new NsRequestProcessingException(message);
+    }
+
+    private void doInitialTerminateChecks(final String nsInstanceId, final TerminateNsRequest terminateNsRequest) {
+        if (isNotImmediateTerminateRequest(terminateNsRequest)) {
+            final String message = "TerminateNsRequest received with terminateTime: "
+                    + terminateNsRequest.getTerminationTime()
+                    + "\nOnly immediate Terminate requests are currently supported \n(i.e., terminateTime field must not be set).";
+            logger.error(message);
+            throw new NsRequestProcessingException(message);
+        }
+
+        final NfvoNsInst nfvoNsInst = getNfvoNsInst(nsInstanceId);
+        if (isNotInstantiated(nfvoNsInst)) {
+            final String message = "TerminateNsRequest received: " + terminateNsRequest + " for nsInstanceId: "
+                    + nsInstanceId + "\nUnable to terminate.  NS Instance is already in NOT_INSTANTIATED state."
+                    + "\nThis method can only be used with an NS instance in the INSTANTIATED state.";
+            logger.error(message);
+            throw new NsRequestProcessingException(message);
+        }
+    }
+
+    private boolean isNotImmediateTerminateRequest(final TerminateNsRequest terminateNsRequest) {
+        return terminateNsRequest.getTerminationTime() != null;
+    }
+
+    private boolean isNotInstantiated(final NfvoNsInst nfvoNsInst) {
+        return State.NOT_INSTANTIATED.equals(nfvoNsInst.getStatus());
+    }
+
+    private NfvoNsInst getNfvoNsInst(final String nsInstId) {
+        logger.info("Getting NfvoNsInst with nsInstId: {}", nsInstId);
+        final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsInstId);
+
+        if (optionalNfvoNsInst.isEmpty()) {
+            final String message = "No matching NS Instance for id: " + nsInstId + " found in database.";
+            throw new NsRequestProcessingException(message);
+        }
+
+        return optionalNfvoNsInst.get();
+    }
+
     private ImmutablePair<String, JobStatusEnum> waitForJobToFinish(final String jobId,
             final ImmutableSet<JobStatusEnum> jobFinishedStates) {
         try {
@@ -200,7 +289,7 @@ public class JobExecutorService {
             JobStatusEnum currentJobStatus = null;
             while (timeOutTime > System.currentTimeMillis()) {
 
-                final Optional<NfvoJob> optional = databaseServiceProvider.getJob(jobId);
+                final Optional<NfvoJob> optional = databaseServiceProvider.getRefreshedJob(jobId);
 
                 if (optional.isEmpty()) {
                     logger.error("Unable to find Job using jobId: {}", jobId);
@@ -209,8 +298,8 @@ public class JobExecutorService {
 
                 final NfvoJob nfvoJob = optional.get();
                 currentJobStatus = nfvoJob.getStatus();
-                logger.info("Received job status response: \n ", nfvoJob);
-                if (jobFinishedStates.contains(nfvoJob.getStatus())) {
+                logger.debug("Received job status response: \n {}", nfvoJob);
+                if (jobFinishedStates.contains(currentJobStatus)) {
                     logger.info("Job finished \n {}", currentJobStatus);
                     return ImmutablePair.of(nfvoJob.getProcessInstanceId(), currentJobStatus);
                 }
@@ -249,4 +338,13 @@ public class JobExecutorService {
         return variables;
     }
 
+    private Map<String, Object> getVariables(final String nsInstanceId, final String jobId, final String occId,
+            final TerminateNsRequest terminateNsRequest) {
+        final Map<String, Object> variables = new HashMap<>();
+        variables.put(NS_INSTANCE_ID_PARAM_NAME, nsInstanceId);
+        variables.put(JOB_ID_PARAM_NAME, jobId);
+        variables.put(OCC_ID_PARAM_NAME, occId);
+        variables.put(TERMINATE_NS_REQUEST_PARAM_NAME, terminateNsRequest);
+        return variables;
+    }
 }
index 99116da..e6905b8 100644 (file)
@@ -21,6 +21,8 @@ package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
 
 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME;
 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.JOB_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OCC_ID_PARAM_NAME;
 import java.time.LocalDateTime;
 import java.util.Optional;
 import org.camunda.bpm.engine.delegate.BpmnError;
@@ -28,6 +30,9 @@ import org.camunda.bpm.engine.delegate.DelegateExecution;
 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum;
 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob;
 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJobStatus;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.OperationStateEnum;
 import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
 import org.onap.so.etsi.nfvo.ns.lcm.model.InlineResponse400;
 import org.slf4j.Logger;
@@ -35,6 +40,7 @@ import org.slf4j.LoggerFactory;
 
 /**
  * @author Waqas Ikram (waqas.ikram@est.tech)
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
  *
  */
 public abstract class AbstractNetworkServiceTask {
@@ -90,6 +96,49 @@ public abstract class AbstractNetworkServiceTask {
 
     }
 
+    public void updateNsLcmOpOccStatusToCompleted(final DelegateExecution execution) {
+        logger.info("Executing updateNsLcmOpOccStatusToCompleted ...");
+        final String occId = (String) execution.getVariable(OCC_ID_PARAM_NAME);
+
+        final Optional<NsLcmOpOcc> optional = databaseServiceProvider.getNsLcmOpOcc(occId);
+
+        if (optional.isEmpty()) {
+            final String message = "Unable to find record for NSLcmOpOcc in database using id: " + occId;
+            logger.error(message);
+            abortOperation(execution, message);
+        }
+
+        final NsLcmOpOcc nsLcmOpOcc = optional.get();
+        final OperationStateEnum operationStateCompleted = OperationStateEnum.COMPLETED;
+        logger.info("Setting operation state to {} for id: {}", operationStateCompleted, occId);
+        nsLcmOpOcc.setOperationState(operationStateCompleted);
+        databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc);
+
+        logger.info("Finished executing updateNsLcmOpOccStatusToCompleted ...");
+
+    }
+
+    public void updateNsLcmOpOccStatusToFailed(final DelegateExecution execution) {
+        logger.info("Executing updateNsLcmOpOccStatusToFailed ...");
+        final String occId = (String) execution.getVariable(OCC_ID_PARAM_NAME);
+
+        final Optional<NsLcmOpOcc> optional = databaseServiceProvider.getNsLcmOpOcc(occId);
+
+        if (optional.isPresent()) {
+            final NsLcmOpOcc nsLcmOpOcc = optional.get();
+            final OperationStateEnum operationStateFailed = OperationStateEnum.FAILED;
+            logger.info("Setting operation state to {} for id: {}", operationStateFailed, occId);
+            nsLcmOpOcc.setOperationState(operationStateFailed);
+
+            databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc);
+        } else {
+            logger.error("Unable to find record for NSLcmOpOcc in database using id: {}", occId);
+        }
+
+        logger.info("Finished executing updateNsLcmOpOccStatusToFailed ...");
+
+    }
+
     protected void abortOperation(final DelegateExecution execution, final String message) {
         abortOperation(execution, message, new InlineResponse400().detail(message));
     }
@@ -104,7 +153,7 @@ public abstract class AbstractNetworkServiceTask {
     private NfvoJob getNfvoJob(final DelegateExecution execution) {
         final String jobId = (String) execution.getVariable(JOB_ID_PARAM_NAME);
         final Optional<NfvoJob> optional = databaseServiceProvider.getJob(jobId);
-        if (!optional.isPresent()) {
+        if (optional.isEmpty()) {
             final String message = "Unable to find job using job id: " + jobId;
             logger.error(message);
             execution.setVariable(CREATE_NS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME,
@@ -114,4 +163,22 @@ public abstract class AbstractNetworkServiceTask {
         }
         return optional.get();
     }
+
+    protected NfvoNsInst getNfvoNsInst(final DelegateExecution execution) {
+        final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+        return getNfvoNsInst(execution, nsInstId);
+    }
+
+    protected NfvoNsInst getNfvoNsInst(final DelegateExecution execution, final String nsInstId) {
+        logger.info("Getting NfvoNsInst to update with nsInstId: {}", nsInstId);
+        final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsInstId);
+
+        if (optionalNfvoNsInst.isEmpty()) {
+            final String message = "Unable to find NS Instance in database using id: " + nsInstId;
+            abortOperation(execution, message);
+        }
+
+        return optionalNfvoNsInst.get();
+    }
+
 }
index c33c67e..251e694 100644 (file)
@@ -219,16 +219,4 @@ public class CreateInstantiateVnfTask extends AbstractNetworkServiceTask {
         databaseServiceProvider.saveNfvoNfInst(nfvoNfInst);
     }
 
-    private NfvoNsInst getNfvoNsInst(final DelegateExecution execution, final String nsInstId) {
-        logger.info("Getting NfvoNsInst to update with nsInstId: {}", nsInstId);
-        final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsInstId);
-
-        if (!optionalNfvoNsInst.isPresent()) {
-            final String message = "Unable to find NS Instance in datababse using id: " + nsInstId;
-            abortOperation(execution, message);
-        }
-
-        return optionalNfvoNsInst.get();
-    }
-
 }
index 8d21204..6774fad 100644 (file)
@@ -55,6 +55,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 /**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
  * @author Andrew Lamb (andrew.a.lamb@est.tech)
  *
  */
@@ -272,50 +273,6 @@ public class InstantiateNsTask extends AbstractNetworkServiceTask {
         setJobStatusToError(execution, "Instantiate NS workflow process failed");
     }
 
-
-    public void updateNsLcmOpOccStatusToCompleted(final DelegateExecution execution) {
-        logger.info("Executing updateNsLcmOpOccStatusToCompleted ...");
-        final String occId = (String) execution.getVariable(OCC_ID_PARAM_NAME);
-
-        final Optional<NsLcmOpOcc> optional = databaseServiceProvider.getNsLcmOpOcc(occId);
-
-        if (!optional.isPresent()) {
-            final String message = "Unable to find record for NSLcmOpOcc in database using id: " + occId;
-            logger.error(message);
-            abortOperation(execution, message);
-        }
-
-        final NsLcmOpOcc nsLcmOpOcc = optional.get();
-        final OperationStateEnum operationStateCompleted = OperationStateEnum.COMPLETED;
-        logger.info("Setting operation state to {} for id: {}", operationStateCompleted, occId);
-        nsLcmOpOcc.setOperationState(operationStateCompleted);
-        databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc);
-
-        logger.info("Finished executing updateNsLcmOpOccStatusToCompleted ...");
-
-    }
-
-    public void updateNsLcmOpOccStatusToFailed(final DelegateExecution execution) {
-        logger.info("Executing updateNsLcmOpOccStatusToFailed ...");
-        final String occId = (String) execution.getVariable(OCC_ID_PARAM_NAME);
-
-        final Optional<NsLcmOpOcc> optional = databaseServiceProvider.getNsLcmOpOcc(occId);
-
-        if (optional.isPresent()) {
-            final NsLcmOpOcc nsLcmOpOcc = optional.get();
-            final OperationStateEnum operationStateFailed = OperationStateEnum.FAILED;
-            logger.info("Setting operation state to {} for id: {}", operationStateFailed, occId);
-            nsLcmOpOcc.setOperationState(operationStateFailed);
-
-            databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc);
-        } else {
-            logger.error("Unable to find record for NSLcmOpOcc in database using id: {}", occId);
-        }
-
-        logger.info("Finished executing updateNsLcmOpOccStatusToFailed ...");
-
-    }
-
     private NsdInfo getNsdInfo(final DelegateExecution execution, final String nsPackageId) {
         try {
             final Optional<NsdInfo> optional =
@@ -395,22 +352,4 @@ public class InstantiateNsTask extends AbstractNetworkServiceTask {
 
     }
 
-    private NfvoNsInst getNfvoNsInst(final DelegateExecution execution) {
-        final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
-        return getNfvoNsInst(execution, nsInstId);
-    }
-
-    private NfvoNsInst getNfvoNsInst(final DelegateExecution execution, final String nsInstId) {
-        logger.info("Getting NfvoNsInst to update with nsInstId: {}", nsInstId);
-        final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsInstId);
-
-        if (!optionalNfvoNsInst.isPresent()) {
-            final String message = "Unable to find NS Instance in database using id: " + nsInstId;
-            abortOperation(execution, message);
-        }
-
-        return optionalNfvoNsInst.get();
-    }
-
-
 }
index e27e0c1..e4dc3d5 100644 (file)
@@ -57,7 +57,7 @@ public abstract class MonitorSol003AdapterNodeTask extends AbstractNetworkServic
             final Optional<GenericVnf> aaiGenericVnfOptional = aaiServiceProvider.getGenericVnf(vnfId);
 
             if (!aaiGenericVnfOptional.isPresent()) {
-                abortOperation(execution, "Unable to invoke Sol003 adapter for create and instantiate vnfId" + vnfId);
+                abortOperation(execution, "Unable to find generic vnf in A&AI using vnfId" + vnfId);
             }
             final GenericVnf genericVnf = aaiGenericVnfOptional.get();
             final String orchestrationStatus = genericVnf.getOrchestrationStatus();
@@ -89,4 +89,8 @@ public abstract class MonitorSol003AdapterNodeTask extends AbstractNetworkServic
         LOGGER.error(message);
         abortOperation(execution, message);
     }
+
+    AaiServiceProvider getAaiServiceProvider() {
+        return aaiServiceProvider;
+    }
 }
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterTerminateJobTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterTerminateJobTask.java
new file mode 100644 (file)
index 0000000..d854444
--- /dev/null
@@ -0,0 +1,106 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.DeleteVnfResponse;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.OPERATION_STATUS_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.DELETE_VNF_RESPONSE_PARAM_NAME;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ *
+ */
+@Component
+public class MonitorSol003AdapterTerminateJobTask extends MonitorSol003AdapterJobTask {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(MonitorSol003AdapterTerminateJobTask.class);
+
+    @Autowired
+    public MonitorSol003AdapterTerminateJobTask(final Sol003AdapterServiceProvider sol003AdapterServiceProvider,
+            final DatabaseServiceProvider databaseServiceProvider) {
+        super(sol003AdapterServiceProvider, databaseServiceProvider);
+    }
+
+    public void getCurrentOperationStatus(final DelegateExecution execution) {
+        try {
+            LOGGER.debug("Executing getCurrentOperationStatus  ...");
+            final DeleteVnfResponse deleteVnfResponse =
+                    (DeleteVnfResponse) execution.getVariable(DELETE_VNF_RESPONSE_PARAM_NAME);
+            execution.setVariable(OPERATION_STATUS_PARAM_NAME,
+                    getOperationStatus(execution, deleteVnfResponse.getJobId()));
+            LOGGER.debug("Finished executing getCurrentOperationStatus ...");
+        } catch (final Exception exception) {
+            final String message = "Unable to invoke get current Operation status";
+            LOGGER.error(message, exception);
+            abortOperation(execution, message);
+
+        }
+    }
+
+    /**
+     * Log and throw exception on timeout for job status
+     *
+     * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl}
+     */
+    public void timeOutLogFailure(final DelegateExecution execution) {
+        final String message = "Termination operation time out";
+        LOGGER.error(message);
+        abortOperation(execution, message);
+    }
+
+    /**
+     * Check the final status of termination throw exception if not completed successfully
+     *
+     * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl}
+     */
+    public void checkIfOperationWasSuccessful(final DelegateExecution execution) {
+        LOGGER.debug("Executing checkIfOperationWasSuccessful  ...");
+        final OperationStateEnum operationStatus =
+                (OperationStateEnum) execution.getVariable(OPERATION_STATUS_PARAM_NAME);
+        final DeleteVnfResponse deleteVnfResponse =
+                (DeleteVnfResponse) execution.getVariable(DELETE_VNF_RESPONSE_PARAM_NAME);
+
+        if (operationStatus == null) {
+            final String message =
+                    "Unable to terminate, jobId: " + (deleteVnfResponse != null ? deleteVnfResponse.getJobId() : "null")
+                            + "Unable to retrieve OperationStatus";
+            LOGGER.error(message);
+            abortOperation(execution, message);
+        }
+        if (operationStatus != OperationStateEnum.COMPLETED) {
+            final String message =
+                    "Unable to terminate, jobId: " + (deleteVnfResponse != null ? deleteVnfResponse.getJobId() : "null")
+                            + " OperationStatus: " + operationStatus;
+            LOGGER.error(message);
+            abortOperation(execution, message);
+        }
+
+        LOGGER.debug("Successfully completed termination of job {}", deleteVnfResponse);
+    }
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterTerminateNodeTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/MonitorSol003AdapterTerminateNodeTask.java
new file mode 100644 (file)
index 0000000..f38bdba
--- /dev/null
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ *
+ */
+@Component
+public class MonitorSol003AdapterTerminateNodeTask extends MonitorSol003AdapterNodeTask {
+
+    public static final String DELETE_VNF_NODE_STATUS = "deleteVnfNodeStatus";
+    public static final String VNF_ASSIGNED = "Assigned";
+
+    @Autowired
+    public MonitorSol003AdapterTerminateNodeTask(final DatabaseServiceProvider databaseServiceProvider,
+            final AaiServiceProvider aaiServiceProvider) {
+        super(databaseServiceProvider, aaiServiceProvider);
+    }
+
+    @Override
+    public String getNodeStatusVariableName() {
+        return DELETE_VNF_NODE_STATUS;
+    }
+
+    @Override
+    public boolean isOrchestrationStatusValid(final String orchestrationStatus) {
+        return VNF_ASSIGNED.equalsIgnoreCase(orchestrationStatus);
+    }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/TerminateNsTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/TerminateNsTask.java
new file mode 100644 (file)
index 0000000..972e4d6
--- /dev/null
@@ -0,0 +1,145 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import java.util.ArrayList;
+import java.util.List;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.STARTED;
+
+/**
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ *
+ */
+@Component
+public class TerminateNsTask extends AbstractNetworkServiceTask {
+
+    private static final String IS_NS_TERMINATION_SUCCESSFUL_PARAM_NAME = "isNsTerminationSuccessful";
+    private static final Logger logger = LoggerFactory.getLogger(TerminateNsTask.class);
+
+    @Autowired
+    public TerminateNsTask(final DatabaseServiceProvider databaseServiceProvider) {
+        super(databaseServiceProvider);
+    }
+
+    public void setJobStatusToStarted(final DelegateExecution execution) {
+        setJobStatus(execution, STARTED, "Terminate NS workflow process started");
+    }
+
+    public void setJobStatusToFinished(final DelegateExecution execution) {
+        setJobStatus(execution, FINISHED, "Terminate NS workflow process finished");
+    }
+
+    public void setJobStatusToError(final DelegateExecution execution) {
+        updateNsInstanceStatus(execution, State.FAILED);
+        setJobStatusToError(execution, "Terminate NS workflow process failed");
+    }
+
+    public void updateNsInstanceStatusToTerminating(final DelegateExecution execution) {
+        logger.info("Executing updateNsInstanceStatusToTerminating");
+        setJobStatus(execution, IN_PROGRESS, "Updating NfvoNsInst Status to " + State.TERMINATING);
+        updateNsInstanceStatus(execution, State.TERMINATING);
+        logger.info("Finished executing updateNsInstanceStatusToTerminating  ...");
+    }
+
+    public void updateNsInstanceStatusToNotInstantiated(final DelegateExecution execution) {
+        logger.info("Executing updateNsInstanceStatusToNotInstantiated");
+        setJobStatus(execution, IN_PROGRESS, "Updating NfvoNsInst Status to " + State.NOT_INSTANTIATED);
+        updateNsInstanceStatus(execution, State.NOT_INSTANTIATED);
+        logger.info("Finished executing updateNsInstanceStatusToNotInstantiated  ...");
+    }
+
+    public void getVnfIdsInNs(final DelegateExecution execution) {
+        logger.info("Executing getVnfIdsInNs ...");
+        setJobStatus(execution, IN_PROGRESS, "Getting Each VnfId In Ns");
+        final List<String> nfvoNfInstIds = getNfvoNfInstIds(execution);
+        execution.setVariable(CamundaVariableNameConstants.NFVO_NF_INST_IDS_PARAM_NAME, nfvoNfInstIds);
+        logger.info("Finished executing getVnfIdsInNs ...");
+    }
+
+    public void checkIfVnfTerminationWasSuccessful(final DelegateExecution execution) {
+        logger.info("Executing checkIfVnfTerminationWasSuccessful");
+
+        final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+        final List<NfvoNfInst> nfInstances = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId);
+
+        if ((nfInstances != null) && !(nfInstances.isEmpty())) {
+            final String message = "Found NF Instances";
+            nfInstances.stream().forEach(instance -> {
+                logger.error("VNF : {} {} termination failed", instance.getNfInstId(), instance.getName());
+                execution.setVariable(IS_NS_TERMINATION_SUCCESSFUL_PARAM_NAME, false);
+            });
+            abortOperation(execution, message);
+        }
+
+        execution.setVariable(IS_NS_TERMINATION_SUCCESSFUL_PARAM_NAME, true);
+        logger.info("Finished executing checkIfVnfTerminationWasSuccessful");
+    }
+
+    public void logTimeOut(final DelegateExecution execution) {
+        logger.error("Vnf termination timedOut ...");
+        final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+        final List<NfvoNfInst> nfInstances = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId);
+        if (nfInstances != null) {
+            nfInstances.stream().forEach(instance -> {
+                logger.info("Current status {} of vnf: {}", instance.getStatus(), instance.getName());
+            });
+        }
+    }
+
+    private void updateNsInstanceStatus(final DelegateExecution execution, final State nsStatus) {
+        final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution);
+        logger.info("Updating NfvoNsInst Status to {} and saving to DB", nsStatus);
+        nfvoNsInst.setStatus(nsStatus);
+        databaseServiceProvider.saveNfvoNsInst(nfvoNsInst);
+    }
+
+    private List<String> getNfvoNfInstIds(final DelegateExecution execution) {
+        final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
+        logger.info("Getting NfvoNfInstList using nsInstId: {}", nsInstId);
+        final List<NfvoNfInst> nfvoNfInstList = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId);
+
+        if (nfvoNfInstList.size() == 0) {
+            final String message = "Unable to find NF Instances in database using id: " + nsInstId;
+            abortOperation(execution, message);
+        }
+
+        final List<String> vnfIdsList = new ArrayList<>();
+
+        nfvoNfInstList.stream().forEach(nfvoNfInst -> {
+            vnfIdsList.add(nfvoNfInst.getNfInstId());
+        });
+
+        return vnfIdsList;
+    }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/TerminateVnfTask.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/tasks/TerminateVnfTask.java
new file mode 100644 (file)
index 0000000..15eee22
--- /dev/null
@@ -0,0 +1,187 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
+
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.DeleteVnfResponse;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.aai.AaiServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterServiceProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
+import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import java.util.Optional;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NF_INST_ID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.DELETE_VNF_RESPONSE_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.TERMINATE_VNF_VNFID_PARAM_NAME;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.ERROR;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED;
+import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS;
+
+/**
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ */
+@Component
+public class TerminateVnfTask extends AbstractNetworkServiceTask {
+    private static final Logger logger = LoggerFactory.getLogger(TerminateVnfTask.class);
+    private final AaiServiceProvider aaiServiceProvider;
+    private final Sol003AdapterServiceProvider sol003AdapterServiceProvider;
+
+    @Autowired
+    public TerminateVnfTask(final DatabaseServiceProvider databaseServiceProvider,
+            final AaiServiceProvider aaiServiceProvider,
+            final Sol003AdapterServiceProvider sol003AdapterServiceProvider) {
+        super(databaseServiceProvider);
+        this.aaiServiceProvider = aaiServiceProvider;
+        this.sol003AdapterServiceProvider = sol003AdapterServiceProvider;
+    }
+
+    public void checkIfNfInstanceExistsInDb(final DelegateExecution execution) {
+        logger.info("Executing checkIfNfInstanceInDb");
+        final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+        logger.info("vnfId: {}", vnfId);
+        execution.setVariable(NF_INST_ID_PARAM_NAME, vnfId);
+
+        setJobStatus(execution, JobStatusEnum.IN_PROGRESS,
+                "Checking if VNF Instance with id: " + vnfId + " exists in database.");
+        if (!databaseServiceProvider.isNfInstExists(vnfId)) {
+            abortOperation(execution,
+                    "VNF instance with id: " + vnfId + " does not exist in database, so will not be terminated.");
+        }
+        logger.info("Finished executing checkIfNfInstanceInDb  ...");
+
+    }
+
+    public void invokeTerminateRequest(final DelegateExecution execution) {
+        logger.info("Executing invokeTerminateRequest");
+        final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+
+        try {
+            setJobStatus(execution, IN_PROGRESS, "Invoking SOL003 adapter for terminating VNF with vnfId: " + vnfId);
+
+            final Optional<DeleteVnfResponse> optional = sol003AdapterServiceProvider.invokeTerminationRequest(vnfId);
+
+            if (optional.isEmpty()) {
+                final String errorMessage = "Unexpected error while processing terminate request for vnfId: " + vnfId;
+                logger.error(errorMessage);
+                abortOperation(execution, errorMessage);
+            }
+
+            final DeleteVnfResponse vnfResponse = optional.get();
+
+            logger.info("Vnf delete response: {}", vnfResponse);
+            execution.setVariable(DELETE_VNF_RESPONSE_PARAM_NAME, vnfResponse);
+            setJobStatus(execution, IN_PROGRESS, "Successfully invoked SOL003 adapter terminate VNF with vnfId: "
+                    + vnfId + " DeleteVnfResponse Job Id: " + vnfResponse.getJobId());
+            logger.debug("Finished executing invokeTerminateRequest ...");
+        } catch (final Exception exception) {
+            final String message = "Unable to invoke terminate request for vnfId: " + vnfId;
+            logger.error(message, exception);
+            abortOperation(execution, message);
+        }
+
+    }
+
+    public void deleteGenericVnfFromAai(final DelegateExecution execution) {
+        logger.info("Executing deleteGenericVnfFromAai");
+        final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+
+        try {
+            setJobStatus(execution, IN_PROGRESS, "Deleting GenericVnf record from AAI for vnfId: " + vnfId);
+            aaiServiceProvider.deleteGenericVnf(vnfId);
+
+        } catch (final Exception exception) {
+            final String message = "Unable to Delete GenericVnf from AAI for vnfId: " + vnfId;
+            logger.error(message, exception);
+            abortOperation(execution, message);
+        }
+
+        logger.info("Finished executing deleteGenericVnfFromAai ...");
+    }
+
+    public void deleteNfInstanceFromDb(final DelegateExecution execution) {
+        logger.info("Executing deleteNfInstanceFromDb");
+        final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+
+        setJobStatus(execution, IN_PROGRESS, "Deleting NF Instance record from Database for vnfId: " + vnfId);
+        databaseServiceProvider.deleteNfvoNfInst(vnfId);
+
+        setJobStatus(execution, FINISHED, "Successfully finished terminating VNF with vnfId: " + vnfId);
+        logger.info("Finished executing deleteNfInstanceFromDb ...");
+    }
+
+    public void updateNfInstanceStatusToTerminating(final DelegateExecution execution) {
+        logger.info("Executing updateNfInstanceStatusToTerminating");
+
+        updateNfInstanceStatus(execution, State.TERMINATING);
+        final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+        setJobStatus(execution, IN_PROGRESS,
+                "Terminating VNF with vnfId: " + vnfId + " will set status to " + State.TERMINATING);
+
+        logger.info("Finished executing updateNfInstanceStatusToTerminating  ...");
+
+    }
+
+    public void updateNfInstanceStatusToNotInstantiated(final DelegateExecution execution) {
+        logger.info("Executing updateNfInstanceStatusToNotInstantiated");
+
+        updateNfInstanceStatus(execution, State.NOT_INSTANTIATED);
+        final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+        setJobStatus(execution, IN_PROGRESS,
+                "Successfully terminated VNF with vnfId: " + vnfId + " will set status to " + State.NOT_INSTANTIATED);
+
+        logger.info("Finished executing updateNfInstanceStatusToInstantiated  ...");
+
+    }
+
+    public void updateNfInstanceStatusToFailed(final DelegateExecution execution) {
+        logger.info("Executing updateNfInstanceStatusToFailed");
+
+        updateNfInstanceStatus(execution, State.FAILED);
+        final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+        setJobStatus(execution, ERROR,
+                "Failed to terminate VNF with vnfId: " + vnfId + " will set status to " + State.FAILED);
+
+        logger.info("Finished executing updateNfInstanceStatusToFailed  ...");
+
+    }
+
+    private void updateNfInstanceStatus(final DelegateExecution execution, final State vnfStatus) {
+        final String vnfId = (String) execution.getVariable(TERMINATE_VNF_VNFID_PARAM_NAME);
+
+        final Optional<NfvoNfInst> optional = databaseServiceProvider.getNfvoNfInst(vnfId);
+        if (optional.isEmpty()) {
+            final String message = "Unable to find NfvoNfInst record in database using vnfId: " + vnfId;
+            logger.error(message);
+
+            abortOperation(execution, message);
+
+        }
+
+        final NfvoNfInst nfvoNfInst = optional.get();
+        nfvoNfInst.setStatus(vnfStatus);
+        databaseServiceProvider.saveNfvoNfInst(nfvoNfInst);
+    }
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterTerminateJob.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterTerminateJob.bpmn
new file mode 100644 (file)
index 0000000..1181a49
--- /dev/null
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_12gnsyw" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.2.0">
+  <bpmn:process id="MonitorSol003AdapterTerminateJob" name="MonitorSol003AdapterTerminateJob" isExecutable="true">
+    <bpmn:startEvent id="StartEvent_1">
+      <bpmn:outgoing>SequenceFlow_1x3tbl0</bpmn:outgoing>
+    </bpmn:startEvent>
+    <bpmn:endEvent id="EndEvent_0rf1gde">
+      <bpmn:incoming>SequenceFlow_1543qy7</bpmn:incoming>
+    </bpmn:endEvent>
+    <bpmn:subProcess id="SubProcess_19j0v63">
+      <bpmn:incoming>SequenceFlow_1x3tbl0</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_1v4yr3f</bpmn:outgoing>
+      <bpmn:startEvent id="StartEvent_01r97z2">
+        <bpmn:outgoing>SequenceFlow_0s1plu9</bpmn:outgoing>
+      </bpmn:startEvent>
+      <bpmn:exclusiveGateway id="ExclusiveGateway_1hkl6yy" default="SequenceFlow_1vmxw9g">
+        <bpmn:incoming>SequenceFlow_153a3kp</bpmn:incoming>
+        <bpmn:outgoing>SequenceFlow_1vmxw9g</bpmn:outgoing>
+        <bpmn:outgoing>SequenceFlow_0is7myf</bpmn:outgoing>
+      </bpmn:exclusiveGateway>
+      <bpmn:intermediateCatchEvent id="IntermediateCatchEvent_1besn3n" name="Wait between checks" camunda:asyncAfter="true">
+        <bpmn:incoming>SequenceFlow_1vmxw9g</bpmn:incoming>
+        <bpmn:outgoing>SequenceFlow_0etw572</bpmn:outgoing>
+        <bpmn:timerEventDefinition id="TimerEventDefinition_0qgh11t">
+          <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT15S</bpmn:timeDuration>
+        </bpmn:timerEventDefinition>
+      </bpmn:intermediateCatchEvent>
+      <bpmn:endEvent id="EndEvent_1ohsce9">
+        <bpmn:incoming>SequenceFlow_0is7myf</bpmn:incoming>
+      </bpmn:endEvent>
+      <bpmn:sequenceFlow id="SequenceFlow_0s1plu9" sourceRef="StartEvent_01r97z2" targetRef="ServiceTask_17jlnng" />
+      <bpmn:sequenceFlow id="SequenceFlow_0etw572" sourceRef="IntermediateCatchEvent_1besn3n" targetRef="ServiceTask_17jlnng" />
+      <bpmn:serviceTask id="ServiceTask_17jlnng" name="&#10;Get Current Operation Status&#10;" camunda:asyncAfter="true" camunda:expression="${MonitorSol003AdapterTerminateJobTask.getCurrentOperationStatus(execution)}">
+        <bpmn:incoming>SequenceFlow_0etw572</bpmn:incoming>
+        <bpmn:incoming>SequenceFlow_0s1plu9</bpmn:incoming>
+        <bpmn:outgoing>SequenceFlow_153a3kp</bpmn:outgoing>
+      </bpmn:serviceTask>
+      <bpmn:sequenceFlow id="SequenceFlow_1vmxw9g" sourceRef="ExclusiveGateway_1hkl6yy" targetRef="IntermediateCatchEvent_1besn3n" />
+      <bpmn:sequenceFlow id="SequenceFlow_0is7myf" sourceRef="ExclusiveGateway_1hkl6yy" targetRef="EndEvent_1ohsce9">
+        <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${MonitorSol003AdapterCreateJobTask.hasOperationFinished(execution)}</bpmn:conditionExpression>
+      </bpmn:sequenceFlow>
+      <bpmn:sequenceFlow id="SequenceFlow_153a3kp" sourceRef="ServiceTask_17jlnng" targetRef="ExclusiveGateway_1hkl6yy" />
+    </bpmn:subProcess>
+    <bpmn:endEvent id="EndEvent_1w3t3t0" name="Timeout Exception">
+      <bpmn:incoming>SequenceFlow_0bcgtzj</bpmn:incoming>
+      <bpmn:terminateEventDefinition id="TerminateEventDefinition_0fjecl3" />
+    </bpmn:endEvent>
+    <bpmn:boundaryEvent id="BoundaryEvent_0xiabzp" name="Overall Wait" attachedToRef="SubProcess_19j0v63">
+      <bpmn:outgoing>SequenceFlow_1i1o9sh</bpmn:outgoing>
+      <bpmn:timerEventDefinition id="TimerEventDefinition_10kqw61">
+        <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT3H</bpmn:timeDuration>
+      </bpmn:timerEventDefinition>
+    </bpmn:boundaryEvent>
+    <bpmn:sequenceFlow id="SequenceFlow_1v4yr3f" sourceRef="SubProcess_19j0v63" targetRef="ServiceTask_1gms128" />
+    <bpmn:sequenceFlow id="SequenceFlow_1i1o9sh" sourceRef="BoundaryEvent_0xiabzp" targetRef="ServiceTask_1s87b92" />
+    <bpmn:sequenceFlow id="SequenceFlow_1x3tbl0" sourceRef="StartEvent_1" targetRef="SubProcess_19j0v63" />
+    <bpmn:serviceTask id="ServiceTask_1s87b92" name="&#10;Time Out Log Failure&#10;" camunda:asyncAfter="true" camunda:expression="${MonitorSol003AdapterTerminateJobTask.timeOutLogFailure(execution)}">
+      <bpmn:incoming>SequenceFlow_1i1o9sh</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_0bcgtzj</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="SequenceFlow_0bcgtzj" sourceRef="ServiceTask_1s87b92" targetRef="EndEvent_1w3t3t0" />
+    <bpmn:serviceTask id="ServiceTask_1gms128" name="&#10;Check if operation was successful&#10;" camunda:asyncAfter="true" camunda:expression="${MonitorSol003AdapterTerminateJobTask.checkIfOperationWasSuccessful(execution)}">
+      <bpmn:incoming>SequenceFlow_1v4yr3f</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_1543qy7</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="SequenceFlow_1543qy7" sourceRef="ServiceTask_1gms128" targetRef="EndEvent_0rf1gde" />
+  </bpmn:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="MonitorSol003AdapterTerminateJob">
+      <bpmndi:BPMNEdge id="SequenceFlow_1543qy7_di" bpmnElement="SequenceFlow_1543qy7">
+        <di:waypoint x="1023" y="118" />
+        <di:waypoint x="1102" y="118" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0bcgtzj_di" bpmnElement="SequenceFlow_0bcgtzj">
+        <di:waypoint x="1023" y="340" />
+        <di:waypoint x="1102" y="340" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1x3tbl0_di" bpmnElement="SequenceFlow_1x3tbl0">
+        <di:waypoint x="197" y="348" />
+        <di:waypoint x="301" y="348" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1i1o9sh_di" bpmnElement="SequenceFlow_1i1o9sh">
+        <di:waypoint x="842" y="340" />
+        <di:waypoint x="923" y="340" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1v4yr3f_di" bpmnElement="SequenceFlow_1v4yr3f">
+        <di:waypoint x="563" y="248" />
+        <di:waypoint x="563" y="118" />
+        <di:waypoint x="923" y="118" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+        <dc:Bounds x="161" y="330" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="EndEvent_0rf1gde_di" bpmnElement="EndEvent_0rf1gde">
+        <dc:Bounds x="1102" y="100" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="SubProcess_19j0v63_di" bpmnElement="SubProcess_19j0v63" isExpanded="true">
+        <dc:Bounds x="301" y="248" width="523" height="200" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_153a3kp_di" bpmnElement="SequenceFlow_153a3kp">
+        <di:waypoint x="525" y="324" />
+        <di:waypoint x="609" y="324" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0is7myf_di" bpmnElement="SequenceFlow_0is7myf">
+        <di:waypoint x="659" y="324" />
+        <di:waypoint x="722" y="324" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1vmxw9g_di" bpmnElement="SequenceFlow_1vmxw9g">
+        <di:waypoint x="634" y="349" />
+        <di:waypoint x="634" y="396" />
+        <di:waypoint x="586" y="396" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0etw572_di" bpmnElement="SequenceFlow_0etw572">
+        <di:waypoint x="550" y="396" />
+        <di:waypoint x="486" y="396" />
+        <di:waypoint x="486" y="367" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0s1plu9_di" bpmnElement="SequenceFlow_0s1plu9">
+        <di:waypoint x="366" y="324" />
+        <di:waypoint x="425" y="324" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="StartEvent_01r97z2_di" bpmnElement="StartEvent_01r97z2">
+        <dc:Bounds x="330" y="306" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ExclusiveGateway_1hkl6yy_di" bpmnElement="ExclusiveGateway_1hkl6yy" isMarkerVisible="true">
+        <dc:Bounds x="609" y="299" width="50" height="50" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="IntermediateCatchEvent_1besn3n_di" bpmnElement="IntermediateCatchEvent_1besn3n">
+        <dc:Bounds x="550" y="378" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="537" y="421" width="66" height="27" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="EndEvent_1ohsce9_di" bpmnElement="EndEvent_1ohsce9">
+        <dc:Bounds x="722" y="306" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ServiceTask_17jlnng_di" bpmnElement="ServiceTask_17jlnng">
+        <dc:Bounds x="425" y="284" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="EndEvent_1w3t3t0_di" bpmnElement="EndEvent_1w3t3t0">
+        <dc:Bounds x="1102" y="322" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1095" y="282" width="49" height="27" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ServiceTask_1s87b92_di" bpmnElement="ServiceTask_1s87b92">
+        <dc:Bounds x="923" y="300" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ServiceTask_1gms128_di" bpmnElement="ServiceTask_1gms128">
+        <dc:Bounds x="923" y="78" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="BoundaryEvent_0xiabzp_di" bpmnElement="BoundaryEvent_0xiabzp">
+        <dc:Bounds x="806" y="322" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="794" y="361" width="61" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn:definitions>
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterTerminateNodeStatus.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/MonitorSol003AdapterTerminateNodeStatus.bpmn
new file mode 100644 (file)
index 0000000..5629ce8
--- /dev/null
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1ko0frn" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.2.0">
+  <bpmn:process id="MonitorSol003AdapterTerminateNodeStatus" name="MonitorSol003AdapterTerminateNodeStatus" isExecutable="true">
+    <bpmn:startEvent id="StartEvent_0k0qfjb">
+      <bpmn:outgoing>SequenceFlow_1miob62</bpmn:outgoing>
+    </bpmn:startEvent>
+    <bpmn:subProcess id="SubProcess_10wotbc">
+      <bpmn:incoming>SequenceFlow_1miob62</bpmn:incoming>
+      <bpmn:startEvent id="StartEvent_0r9qf43">
+        <bpmn:outgoing>SequenceFlow_1moaz0q</bpmn:outgoing>
+      </bpmn:startEvent>
+      <bpmn:exclusiveGateway id="ExclusiveGateway_00xtlfj" default="SequenceFlow_1luu31f">
+        <bpmn:incoming>SequenceFlow_0qvy3sn</bpmn:incoming>
+        <bpmn:outgoing>SequenceFlow_1rxbeqi</bpmn:outgoing>
+        <bpmn:outgoing>SequenceFlow_1luu31f</bpmn:outgoing>
+      </bpmn:exclusiveGateway>
+      <bpmn:intermediateCatchEvent id="IntermediateCatchEvent_0xuznv9" name="Wait between checks" camunda:asyncAfter="true">
+        <bpmn:incoming>SequenceFlow_1luu31f</bpmn:incoming>
+        <bpmn:outgoing>SequenceFlow_09t51ao</bpmn:outgoing>
+        <bpmn:timerEventDefinition id="TimerEventDefinition_0vrbrge">
+          <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT15S</bpmn:timeDuration>
+        </bpmn:timerEventDefinition>
+      </bpmn:intermediateCatchEvent>
+      <bpmn:endEvent id="EndEvent_0tei3i9">
+        <bpmn:incoming>SequenceFlow_1rxbeqi</bpmn:incoming>
+      </bpmn:endEvent>
+      <bpmn:serviceTask id="ServiceTask_0y71su8" name="&#10;Get node status &#10;" camunda:asyncAfter="true" camunda:expression="${MonitorSol003AdapterTerminateNodeTask.getNodeStatus(execution)}">
+        <bpmn:incoming>SequenceFlow_1moaz0q</bpmn:incoming>
+        <bpmn:incoming>SequenceFlow_09t51ao</bpmn:incoming>
+        <bpmn:outgoing>SequenceFlow_0qvy3sn</bpmn:outgoing>
+      </bpmn:serviceTask>
+      <bpmn:sequenceFlow id="SequenceFlow_1rxbeqi" name="&#10;&#10;terminate vnf success&#10;&#10;" sourceRef="ExclusiveGateway_00xtlfj" targetRef="EndEvent_0tei3i9">
+        <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${execution.getVariable("deleteVnfNodeStatus")}</bpmn:conditionExpression>
+      </bpmn:sequenceFlow>
+      <bpmn:sequenceFlow id="SequenceFlow_1luu31f" sourceRef="ExclusiveGateway_00xtlfj" targetRef="IntermediateCatchEvent_0xuznv9" />
+      <bpmn:sequenceFlow id="SequenceFlow_1moaz0q" sourceRef="StartEvent_0r9qf43" targetRef="ServiceTask_0y71su8" />
+      <bpmn:sequenceFlow id="SequenceFlow_0qvy3sn" sourceRef="ServiceTask_0y71su8" targetRef="ExclusiveGateway_00xtlfj" />
+      <bpmn:sequenceFlow id="SequenceFlow_09t51ao" sourceRef="IntermediateCatchEvent_0xuznv9" targetRef="ServiceTask_0y71su8" />
+    </bpmn:subProcess>
+    <bpmn:endEvent id="EndEvent_1b83rci" name="Timeout Exception">
+      <bpmn:incoming>SequenceFlow_0uiqnl8</bpmn:incoming>
+      <bpmn:terminateEventDefinition id="TerminateEventDefinition_12rjfva" />
+    </bpmn:endEvent>
+    <bpmn:serviceTask id="ServiceTask_12qp0ty" name="&#10;Time Out Log Failure&#10;" camunda:asyncAfter="true" camunda:expression="${MonitorSol003AdapterNodeTask.timeOutLogFailue(execution)}">
+      <bpmn:incoming>SequenceFlow_0qcc5x4</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_0uiqnl8</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:boundaryEvent id="BoundaryEvent_1f5o5i9" name="Overall Wait" attachedToRef="SubProcess_10wotbc">
+      <bpmn:outgoing>SequenceFlow_0qcc5x4</bpmn:outgoing>
+      <bpmn:timerEventDefinition id="TimerEventDefinition_1t3ya63">
+        <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT3H</bpmn:timeDuration>
+      </bpmn:timerEventDefinition>
+    </bpmn:boundaryEvent>
+    <bpmn:sequenceFlow id="SequenceFlow_1miob62" sourceRef="StartEvent_0k0qfjb" targetRef="SubProcess_10wotbc" />
+    <bpmn:sequenceFlow id="SequenceFlow_0uiqnl8" sourceRef="ServiceTask_12qp0ty" targetRef="EndEvent_1b83rci" />
+    <bpmn:sequenceFlow id="SequenceFlow_0qcc5x4" sourceRef="BoundaryEvent_1f5o5i9" targetRef="ServiceTask_12qp0ty" />
+  </bpmn:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="MonitorSol003AdapterTerminateNodeStatus">
+      <bpmndi:BPMNEdge id="SequenceFlow_0qcc5x4_di" bpmnElement="SequenceFlow_0qcc5x4">
+        <di:waypoint x="836" y="169" />
+        <di:waypoint x="917" y="169" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0uiqnl8_di" bpmnElement="SequenceFlow_0uiqnl8">
+        <di:waypoint x="1017" y="169" />
+        <di:waypoint x="1096" y="169" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1miob62_di" bpmnElement="SequenceFlow_1miob62">
+        <di:waypoint x="191" y="177" />
+        <di:waypoint x="293" y="177" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="StartEvent_0k0qfjb_di" bpmnElement="StartEvent_0k0qfjb">
+        <dc:Bounds x="155" y="159" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="SubProcess_10wotbc_di" bpmnElement="SubProcess_10wotbc" isExpanded="true">
+        <dc:Bounds x="293" y="77" width="523" height="200" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_09t51ao_di" bpmnElement="SequenceFlow_09t51ao">
+        <di:waypoint x="544" y="225" />
+        <di:waypoint x="451" y="225" />
+        <di:waypoint x="452" y="193" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0qvy3sn_di" bpmnElement="SequenceFlow_0qvy3sn">
+        <di:waypoint x="512" y="153" />
+        <di:waypoint x="603" y="153" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1moaz0q_di" bpmnElement="SequenceFlow_1moaz0q">
+        <di:waypoint x="360" y="153" />
+        <di:waypoint x="412" y="153" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1luu31f_di" bpmnElement="SequenceFlow_1luu31f">
+        <di:waypoint x="628" y="178" />
+        <di:waypoint x="628" y="225" />
+        <di:waypoint x="580" y="225" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1rxbeqi_di" bpmnElement="SequenceFlow_1rxbeqi">
+        <di:waypoint x="653" y="153" />
+        <di:waypoint x="716" y="153" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="653" y="135" width="65" height="80" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="StartEvent_0r9qf43_di" bpmnElement="StartEvent_0r9qf43">
+        <dc:Bounds x="324" y="135" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ExclusiveGateway_00xtlfj_di" bpmnElement="ExclusiveGateway_00xtlfj" isMarkerVisible="true">
+        <dc:Bounds x="603" y="128" width="50" height="50" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="IntermediateCatchEvent_0xuznv9_di" bpmnElement="IntermediateCatchEvent_0xuznv9">
+        <dc:Bounds x="544" y="207" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="532" y="250" width="66" height="27" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="EndEvent_0tei3i9_di" bpmnElement="EndEvent_0tei3i9">
+        <dc:Bounds x="716" y="135" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ServiceTask_0y71su8_di" bpmnElement="ServiceTask_0y71su8">
+        <dc:Bounds x="412" y="113" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="EndEvent_1b83rci_di" bpmnElement="EndEvent_1b83rci">
+        <dc:Bounds x="1096" y="151" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1089" y="111" width="49" height="27" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ServiceTask_12qp0ty_di" bpmnElement="ServiceTask_12qp0ty">
+        <dc:Bounds x="917" y="129" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="BoundaryEvent_1f5o5i9_di" bpmnElement="BoundaryEvent_1f5o5i9">
+        <dc:Bounds x="800" y="151" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="788" y="190" width="61" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn:definitions>
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/TerminateNs.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/TerminateNs.bpmn
new file mode 100644 (file)
index 0000000..36c52c8
--- /dev/null
@@ -0,0 +1,307 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_0mdda96" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.2.0">
+  <bpmn:process id="TerminateNs" name="TerminateNs" isExecutable="true">
+    <bpmn:startEvent id="StartEvent_1" name="Start Process">
+      <bpmn:outgoing>SequenceFlow_16k0f61</bpmn:outgoing>
+    </bpmn:startEvent>
+    <bpmn:sequenceFlow id="SequenceFlow_16k0f61" sourceRef="StartEvent_1" targetRef="Activity_194tqy0" />
+    <bpmn:serviceTask id="Task_0opnwx0" name="Update NS Instance status to TERMINATING" camunda:expression="${TerminateNsTask.updateNsInstanceStatusToTerminating(execution)}">
+      <bpmn:incoming>Flow_04pxtdd</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_0bdznyp</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:endEvent id="EndEvent_0szswbo" name="End Process">
+      <bpmn:incoming>Flow_1pcu8aa</bpmn:incoming>
+    </bpmn:endEvent>
+    <bpmn:sequenceFlow id="SequenceFlow_0bdznyp" sourceRef="Task_0opnwx0" targetRef="Activity_1kikjaf" />
+    <bpmn:serviceTask id="Activity_194tqy0" name="Set Job Status to STARTED" camunda:asyncBefore="true" camunda:expression="${TerminateNsTask.setJobStatusToStarted(execution)}">
+      <bpmn:incoming>SequenceFlow_16k0f61</bpmn:incoming>
+      <bpmn:outgoing>Flow_04pxtdd</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_04pxtdd" sourceRef="Activity_194tqy0" targetRef="Task_0opnwx0" />
+    <bpmn:subProcess id="Activity_0pjxszh" name="Error Handling" triggeredByEvent="true">
+      <bpmn:startEvent id="Event_1rpzcl3" name="error">
+        <bpmn:outgoing>Flow_07bh7l7</bpmn:outgoing>
+        <bpmn:errorEventDefinition id="ErrorEventDefinition_0m2e0oa" />
+      </bpmn:startEvent>
+      <bpmn:endEvent id="Event_1fcw3ei" name="end">
+        <bpmn:incoming>Flow_1wa1jpl</bpmn:incoming>
+      </bpmn:endEvent>
+      <bpmn:serviceTask id="Activity_0ddja9m" name="Set Job Status to ERROR" camunda:asyncBefore="true" camunda:expression="${TerminateNsTask.setJobStatusToError(execution)}">
+        <bpmn:incoming>Flow_0n3dai5</bpmn:incoming>
+        <bpmn:outgoing>Flow_1wa1jpl</bpmn:outgoing>
+      </bpmn:serviceTask>
+      <bpmn:sequenceFlow id="Flow_1wa1jpl" sourceRef="Activity_0ddja9m" targetRef="Event_1fcw3ei" />
+      <bpmn:sequenceFlow id="Flow_07bh7l7" sourceRef="Event_1rpzcl3" targetRef="Activity_1miy3hw" />
+      <bpmn:serviceTask id="Activity_1miy3hw" name="Update NSLcmOpOcc operation status to FAILED" camunda:asyncBefore="true" camunda:expression="${TerminateNsTask.updateNsLcmOpOccStatusToFailed(execution)}">
+        <bpmn:incoming>Flow_07bh7l7</bpmn:incoming>
+        <bpmn:outgoing>Flow_0n3dai5</bpmn:outgoing>
+      </bpmn:serviceTask>
+      <bpmn:sequenceFlow id="Flow_0n3dai5" sourceRef="Activity_1miy3hw" targetRef="Activity_0ddja9m" />
+    </bpmn:subProcess>
+    <bpmn:subProcess id="Activity_0mtscwq" name="Java Exception Handling" triggeredByEvent="true">
+      <bpmn:startEvent id="Event_0lqr6al" name="error">
+        <bpmn:outgoing>Flow_05lo00r</bpmn:outgoing>
+        <bpmn:errorEventDefinition id="ErrorEventDefinition_02lwl19" errorRef="Error_0jsct8p" camunda:errorCodeVariable="BPMN_javaExpCode" camunda:errorMessageVariable="BPMN_javaExpMsg" />
+      </bpmn:startEvent>
+      <bpmn:endEvent id="Event_05ty7c4">
+        <bpmn:incoming>Flow_16aryg5</bpmn:incoming>
+      </bpmn:endEvent>
+      <bpmn:serviceTask id="Activity_1ezu7d4" name="Set Job Status to ERROR" camunda:asyncBefore="true" camunda:expression="${TerminateNsTask.setJobStatusToError(execution)}">
+        <bpmn:incoming>Flow_09zcw2a</bpmn:incoming>
+        <bpmn:outgoing>Flow_16aryg5</bpmn:outgoing>
+      </bpmn:serviceTask>
+      <bpmn:sequenceFlow id="Flow_16aryg5" sourceRef="Activity_1ezu7d4" targetRef="Event_05ty7c4" />
+      <bpmn:sequenceFlow id="Flow_05lo00r" sourceRef="Event_0lqr6al" targetRef="Activity_17leldb" />
+      <bpmn:serviceTask id="Activity_17leldb" name="Update NSLcmOpOcc operation status to FAILED" camunda:asyncBefore="true" camunda:expression="${TerminateNsTask.updateNsLcmOpOccStatusToFailed(execution)}">
+        <bpmn:incoming>Flow_05lo00r</bpmn:incoming>
+        <bpmn:outgoing>Flow_09zcw2a</bpmn:outgoing>
+      </bpmn:serviceTask>
+      <bpmn:sequenceFlow id="Flow_09zcw2a" sourceRef="Activity_17leldb" targetRef="Activity_1ezu7d4" />
+    </bpmn:subProcess>
+    <bpmn:serviceTask id="Activity_1w09i1k" name="Set Job Status to FINISHED" camunda:expression="${TerminateNsTask.setJobStatusToFinished(execution)}">
+      <bpmn:incoming>Flow_1i36dw4</bpmn:incoming>
+      <bpmn:outgoing>Flow_1pcu8aa</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_1pcu8aa" sourceRef="Activity_1w09i1k" targetRef="EndEvent_0szswbo" />
+    <bpmn:callActivity id="Activity_1b2s2wr" name="Terminate Vnfs" calledElement="TerminateVnf">
+      <bpmn:extensionElements>
+        <camunda:in source="jobId" target="jobId" />
+        <camunda:in source="NsInstanceId" target="NsInstanceId" />
+        <camunda:in source="vnfId" target="vnfId" />
+      </bpmn:extensionElements>
+      <bpmn:incoming>Flow_01ju1mj</bpmn:incoming>
+      <bpmn:outgoing>Flow_0mi4nqa</bpmn:outgoing>
+      <bpmn:multiInstanceLoopCharacteristics camunda:asyncAfter="true" camunda:collection="${nfvoNfInstIds}" camunda:elementVariable="vnfId" />
+    </bpmn:callActivity>
+    <bpmn:boundaryEvent id="Event_0rbb817" name="Overall Wait" attachedToRef="Activity_1b2s2wr">
+      <bpmn:outgoing>Flow_17zn7we</bpmn:outgoing>
+      <bpmn:timerEventDefinition id="TimerEventDefinition_13ud1f4">
+        <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT3H</bpmn:timeDuration>
+      </bpmn:timerEventDefinition>
+    </bpmn:boundaryEvent>
+    <bpmn:sequenceFlow id="Flow_17zn7we" sourceRef="Event_0rbb817" targetRef="Activity_16z66xm" />
+    <bpmn:serviceTask id="Activity_1kikjaf" name="Get Vnf IDs in NS" camunda:expression="${TerminateNsTask.getVnfIdsInNs(execution)}">
+      <bpmn:incoming>SequenceFlow_0bdznyp</bpmn:incoming>
+      <bpmn:outgoing>Flow_01ju1mj</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_01ju1mj" sourceRef="Activity_1kikjaf" targetRef="Activity_1b2s2wr" />
+    <bpmn:serviceTask id="Activity_16cvdbw" name="Update NS Instance status to NOT_INSTANTIATED" camunda:expression="${TerminateNsTask.updateNsInstanceStatusToNotInstantiated(execution)}">
+      <bpmn:incoming>Flow_1nieng0</bpmn:incoming>
+      <bpmn:outgoing>Flow_0xptc0r</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_0xptc0r" sourceRef="Activity_16cvdbw" targetRef="Activity_0gkpdft" />
+    <bpmn:endEvent id="Event_1e4bwip">
+      <bpmn:incoming>Flow_10oprxr</bpmn:incoming>
+      <bpmn:incoming>Flow_1p21p1m</bpmn:incoming>
+      <bpmn:errorEventDefinition id="ErrorEventDefinition_0vg6v5r" errorRef="Error_0jsct8p" />
+    </bpmn:endEvent>
+    <bpmn:exclusiveGateway id="Gateway_0nxf0rv" name="is Successful?">
+      <bpmn:incoming>Flow_15m4nm1</bpmn:incoming>
+      <bpmn:outgoing>Flow_1nieng0</bpmn:outgoing>
+      <bpmn:outgoing>Flow_10oprxr</bpmn:outgoing>
+    </bpmn:exclusiveGateway>
+    <bpmn:sequenceFlow id="Flow_1nieng0" name="Yes" sourceRef="Gateway_0nxf0rv" targetRef="Activity_16cvdbw">
+      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{isNsTerminationSuccessful}</bpmn:conditionExpression>
+    </bpmn:sequenceFlow>
+    <bpmn:serviceTask id="Activity_14iwa8x" name="Check if VNF Termination was Successful" camunda:expression="${TerminateNsTask.checkIfVnfTerminationWasSuccessful(execution)}">
+      <bpmn:incoming>Flow_0mi4nqa</bpmn:incoming>
+      <bpmn:outgoing>Flow_15m4nm1</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_0mi4nqa" sourceRef="Activity_1b2s2wr" targetRef="Activity_14iwa8x" />
+    <bpmn:sequenceFlow id="Flow_15m4nm1" sourceRef="Activity_14iwa8x" targetRef="Gateway_0nxf0rv" />
+    <bpmn:serviceTask id="Activity_16z66xm" name="Log TimeOut" camunda:expression="${TerminateNsTask.logTimeOut(execution)}">
+      <bpmn:incoming>Flow_17zn7we</bpmn:incoming>
+      <bpmn:outgoing>Flow_1p21p1m</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_10oprxr" name="No" sourceRef="Gateway_0nxf0rv" targetRef="Event_1e4bwip">
+      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{not isNsTerminationSuccessful}</bpmn:conditionExpression>
+    </bpmn:sequenceFlow>
+    <bpmn:sequenceFlow id="Flow_1p21p1m" sourceRef="Activity_16z66xm" targetRef="Event_1e4bwip" />
+    <bpmn:serviceTask id="Activity_0gkpdft" name="Update NSLcmOpOcc operation status to COMPLETED" camunda:expression="${TerminateNsTask.updateNsLcmOpOccStatusToCompleted(execution)}">
+      <bpmn:incoming>Flow_0xptc0r</bpmn:incoming>
+      <bpmn:outgoing>Flow_1i36dw4</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_1i36dw4" sourceRef="Activity_0gkpdft" targetRef="Activity_1w09i1k" />
+  </bpmn:process>
+  <bpmn:error id="Error_0jsct8p" name="TerminateNsProcessingException" errorCode="TERMINATE_NS_PROCESSING_EXCEPTION" />
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="TerminateNs">
+      <bpmndi:BPMNEdge id="Flow_1i36dw4_di" bpmnElement="Flow_1i36dw4">
+        <di:waypoint x="1680" y="121" />
+        <di:waypoint x="1720" y="121" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1p21p1m_di" bpmnElement="Flow_1p21p1m">
+        <di:waypoint x="1110" y="270" />
+        <di:waypoint x="1332" y="270" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_10oprxr_di" bpmnElement="Flow_10oprxr">
+        <di:waypoint x="1350" y="146" />
+        <di:waypoint x="1350" y="252" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1358" y="196" width="14" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_15m4nm1_di" bpmnElement="Flow_15m4nm1">
+        <di:waypoint x="1110" y="121" />
+        <di:waypoint x="1325" y="121" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0mi4nqa_di" bpmnElement="Flow_0mi4nqa">
+        <di:waypoint x="790" y="121" />
+        <di:waypoint x="1010" y="121" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1nieng0_di" bpmnElement="Flow_1nieng0">
+        <di:waypoint x="1375" y="121" />
+        <di:waypoint x="1430" y="121" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1393" y="103" width="19" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0xptc0r_di" bpmnElement="Flow_0xptc0r">
+        <di:waypoint x="1530" y="121" />
+        <di:waypoint x="1580" y="121" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_01ju1mj_di" bpmnElement="Flow_01ju1mj">
+        <di:waypoint x="650" y="121" />
+        <di:waypoint x="690" y="121" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_17zn7we_di" bpmnElement="Flow_17zn7we">
+        <di:waypoint x="770" y="179" />
+        <di:waypoint x="770" y="270" />
+        <di:waypoint x="1010" y="270" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1pcu8aa_di" bpmnElement="Flow_1pcu8aa">
+        <di:waypoint x="1820" y="121" />
+        <di:waypoint x="1862" y="121" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_04pxtdd_di" bpmnElement="Flow_04pxtdd">
+        <di:waypoint x="360" y="121" />
+        <di:waypoint x="410" y="121" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0bdznyp_di" bpmnElement="SequenceFlow_0bdznyp">
+        <di:waypoint x="510" y="121" />
+        <di:waypoint x="550" y="121" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_16k0f61_di" bpmnElement="SequenceFlow_16k0f61">
+        <di:waypoint x="208" y="121" />
+        <di:waypoint x="260" y="121" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+        <dc:Bounds x="172" y="103" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="157" y="146" width="67" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ServiceTask_1y7xfqt_di" bpmnElement="Task_0opnwx0">
+        <dc:Bounds x="410" y="81" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="EndEvent_0szswbo_di" bpmnElement="EndEvent_0szswbo">
+        <dc:Bounds x="1862" y="103" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1848" y="79" width="63" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_194tqy0_di" bpmnElement="Activity_194tqy0">
+        <dc:Bounds x="260" y="81" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0pjxszh_di" bpmnElement="Activity_0pjxszh" isExpanded="true">
+        <dc:Bounds x="380" y="310" width="510" height="130" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="Flow_0n3dai5_di" bpmnElement="Flow_0n3dai5">
+        <di:waypoint x="600" y="373" />
+        <di:waypoint x="660" y="373" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_07bh7l7_di" bpmnElement="Flow_07bh7l7">
+        <di:waypoint x="438" y="373" />
+        <di:waypoint x="500" y="373" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1wa1jpl_di" bpmnElement="Flow_1wa1jpl">
+        <di:waypoint x="760" y="373" />
+        <di:waypoint x="822" y="373" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="Event_1rpzcl3_di" bpmnElement="Event_1rpzcl3">
+        <dc:Bounds x="402" y="355" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="408" y="398" width="24" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_1fcw3ei_di" bpmnElement="Event_1fcw3ei">
+        <dc:Bounds x="822" y="355" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="832" y="397" width="19" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0ddja9m_di" bpmnElement="Activity_0ddja9m">
+        <dc:Bounds x="660" y="333" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1miy3hw_di" bpmnElement="Activity_1miy3hw">
+        <dc:Bounds x="500" y="333" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0mtscwq_di" bpmnElement="Activity_0mtscwq" isExpanded="true">
+        <dc:Bounds x="380" y="480" width="510" height="130" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="Flow_09zcw2a_di" bpmnElement="Flow_09zcw2a">
+        <di:waypoint x="600" y="543" />
+        <di:waypoint x="660" y="543" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_05lo00r_di" bpmnElement="Flow_05lo00r">
+        <di:waypoint x="438" y="543" />
+        <di:waypoint x="500" y="543" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_16aryg5_di" bpmnElement="Flow_16aryg5">
+        <di:waypoint x="760" y="543" />
+        <di:waypoint x="822" y="543" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="Event_0lqr6al_di" bpmnElement="Event_0lqr6al">
+        <dc:Bounds x="402" y="525" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="409" y="568" width="24" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_05ty7c4_di" bpmnElement="Event_05ty7c4">
+        <dc:Bounds x="822" y="525" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1ezu7d4_di" bpmnElement="Activity_1ezu7d4">
+        <dc:Bounds x="660" y="503" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_17leldb_di" bpmnElement="Activity_17leldb">
+        <dc:Bounds x="500" y="503" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1w09i1k_di" bpmnElement="Activity_1w09i1k">
+        <dc:Bounds x="1720" y="81" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1xjmizv_di" bpmnElement="Activity_1b2s2wr">
+        <dc:Bounds x="690" y="81" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1kikjaf_di" bpmnElement="Activity_1kikjaf">
+        <dc:Bounds x="550" y="81" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_16cvdbw_di" bpmnElement="Activity_16cvdbw">
+        <dc:Bounds x="1430" y="81" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_16umj30_di" bpmnElement="Event_1e4bwip">
+        <dc:Bounds x="1332" y="252" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Gateway_0nxf0rv_di" bpmnElement="Gateway_0nxf0rv" isMarkerVisible="true">
+        <dc:Bounds x="1325" y="96" width="50" height="50" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1320" y="66" width="71" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_14iwa8x_di" bpmnElement="Activity_14iwa8x">
+        <dc:Bounds x="1010" y="81" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_16z66xm_di" bpmnElement="Activity_16z66xm">
+        <dc:Bounds x="1010" y="230" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0gkpdft_di" bpmnElement="Activity_0gkpdft">
+        <dc:Bounds x="1580" y="81" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_0rbb817_di" bpmnElement="Event_0rbb817">
+        <dc:Bounds x="752" y="143" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="700" y="183" width="60" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn:definitions>
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/TerminateVnf.bpmn b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/resources/TerminateVnf.bpmn
new file mode 100644 (file)
index 0000000..994933f
--- /dev/null
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1uf6nd9" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.2.0">
+  <bpmn:process id="TerminateVnf" name="TerminateVnf" isExecutable="true">
+    <bpmn:startEvent id="StartEvent_1">
+      <bpmn:outgoing>Flow_02bjz2v</bpmn:outgoing>
+    </bpmn:startEvent>
+    <bpmn:sequenceFlow id="Flow_02bjz2v" sourceRef="StartEvent_1" targetRef="Activity_1cluqgp" />
+    <bpmn:endEvent id="Event_14qdixj">
+      <bpmn:incoming>Flow_1egtf3w</bpmn:incoming>
+    </bpmn:endEvent>
+    <bpmn:serviceTask id="Activity_1cluqgp" name="Check If NF Instance (VNF) exists in DB" camunda:expression="${TerminateVnfTask.checkIfNfInstanceExistsInDb(execution)}">
+      <bpmn:incoming>Flow_02bjz2v</bpmn:incoming>
+      <bpmn:outgoing>Flow_123uagz</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_123uagz" sourceRef="Activity_1cluqgp" targetRef="Activity_17vixcx" />
+    <bpmn:serviceTask id="ServiceTask_0iry5yw" name="&#10;Invoke VNFM Adapter&#10;" camunda:asyncAfter="true" camunda:expression="${TerminateVnfTask.invokeTerminateRequest(execution)}">
+      <bpmn:incoming>Flow_0in3hgl</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_0xzptc2</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:callActivity id="CallActivity_1yilxx3" name="Monitor Sol003 Adapter Terminate Job" calledElement="MonitorSol003AdapterTerminateJob">
+      <bpmn:extensionElements>
+        <camunda:in source="jobId" target="jobId" />
+        <camunda:in source="deleteVnfResponse" target="deleteVnfResponse" />
+      </bpmn:extensionElements>
+      <bpmn:incoming>SequenceFlow_0xzptc2</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_053tvct</bpmn:outgoing>
+    </bpmn:callActivity>
+    <bpmn:sequenceFlow id="SequenceFlow_0xzptc2" sourceRef="ServiceTask_0iry5yw" targetRef="CallActivity_1yilxx3" />
+    <bpmn:sequenceFlow id="SequenceFlow_053tvct" sourceRef="CallActivity_1yilxx3" targetRef="Activity_0wgjtoy" />
+    <bpmn:serviceTask id="Activity_0g3dip7" name="Update NF Instance (VNF) Status to NOT_INSTANTIATED" camunda:expression="${TerminateVnfTask.updateNfInstanceStatusToNotInstantiated(execution)}">
+      <bpmn:incoming>Flow_1rw8pwu</bpmn:incoming>
+      <bpmn:outgoing>Flow_0srinh7</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_0srinh7" sourceRef="Activity_0g3dip7" targetRef="Activity_1vptrrr" />
+    <bpmn:subProcess id="Activity_0qtgdm9" name="Error Handling" triggeredByEvent="true">
+      <bpmn:startEvent id="Event_08zcwc2" name="error">
+        <bpmn:outgoing>Flow_06q1m6i</bpmn:outgoing>
+        <bpmn:errorEventDefinition id="ErrorEventDefinition_1ppvn77" />
+      </bpmn:startEvent>
+      <bpmn:endEvent id="Event_1wkm29u" name="end">
+        <bpmn:incoming>Flow_0anjylz</bpmn:incoming>
+      </bpmn:endEvent>
+      <bpmn:serviceTask id="Activity_0ltxcii" name="Update NF Instance (VNF) Status to FAILED" camunda:asyncBefore="true" camunda:expression="${TerminateVnfTask.updateNfInstanceStatusToFailed(execution)}">
+        <bpmn:incoming>Flow_06q1m6i</bpmn:incoming>
+        <bpmn:outgoing>Flow_0anjylz</bpmn:outgoing>
+      </bpmn:serviceTask>
+      <bpmn:sequenceFlow id="Flow_06q1m6i" sourceRef="Event_08zcwc2" targetRef="Activity_0ltxcii" />
+      <bpmn:sequenceFlow id="Flow_0anjylz" sourceRef="Activity_0ltxcii" targetRef="Event_1wkm29u" />
+    </bpmn:subProcess>
+    <bpmn:callActivity id="Activity_0wgjtoy" name="Monitor Sol003 Adapter Terminate Node Status" calledElement="MonitorSol003AdapterTerminateNodeStatus">
+      <bpmn:extensionElements>
+        <camunda:in source="NF_INST_ID" target="NF_INST_ID" />
+        <camunda:in source="deleteVnfResponse" target="deleteVnfResponse" />
+      </bpmn:extensionElements>
+      <bpmn:incoming>SequenceFlow_053tvct</bpmn:incoming>
+      <bpmn:outgoing>Flow_1wfvdmt</bpmn:outgoing>
+    </bpmn:callActivity>
+    <bpmn:sequenceFlow id="Flow_1wfvdmt" sourceRef="Activity_0wgjtoy" targetRef="Activity_0lulaof" />
+    <bpmn:sequenceFlow id="Flow_1egtf3w" sourceRef="Activity_1vptrrr" targetRef="Event_14qdixj" />
+    <bpmn:serviceTask id="Activity_1vptrrr" name="Delete NF Instance (VNF) record from DB" camunda:expression="${TerminateVnfTask.deleteNfInstanceFromDb(execution)}">
+      <bpmn:incoming>Flow_0srinh7</bpmn:incoming>
+      <bpmn:outgoing>Flow_1egtf3w</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_0in3hgl" sourceRef="Activity_17vixcx" targetRef="ServiceTask_0iry5yw" />
+    <bpmn:serviceTask id="Activity_17vixcx" name="Update NF Instance (VNF) Status to TERMINATING" camunda:expression="${TerminateVnfTask.updateNfInstanceStatusToTerminating(execution)}">
+      <bpmn:incoming>Flow_123uagz</bpmn:incoming>
+      <bpmn:outgoing>Flow_0in3hgl</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:serviceTask id="Activity_0lulaof" name="Delete Generic VNF From AAI" camunda:expression="${TerminateVnfTask.deleteGenericVnfFromAai(execution)}">
+      <bpmn:incoming>Flow_1wfvdmt</bpmn:incoming>
+      <bpmn:outgoing>Flow_1rw8pwu</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_1rw8pwu" sourceRef="Activity_0lulaof" targetRef="Activity_0g3dip7" />
+  </bpmn:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="TerminateVnf">
+      <bpmndi:BPMNEdge id="Flow_0in3hgl_di" bpmnElement="Flow_0in3hgl">
+        <di:waypoint x="490" y="117" />
+        <di:waypoint x="540" y="117" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1egtf3w_di" bpmnElement="Flow_1egtf3w">
+        <di:waypoint x="1370" y="117" />
+        <di:waypoint x="1432" y="117" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1wfvdmt_di" bpmnElement="Flow_1wfvdmt">
+        <di:waypoint x="940" y="117" />
+        <di:waypoint x="990" y="117" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0srinh7_di" bpmnElement="Flow_0srinh7">
+        <di:waypoint x="1230" y="117" />
+        <di:waypoint x="1270" y="117" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_053tvct_di" bpmnElement="SequenceFlow_053tvct">
+        <di:waypoint x="790" y="117" />
+        <di:waypoint x="840" y="117" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0xzptc2_di" bpmnElement="SequenceFlow_0xzptc2">
+        <di:waypoint x="640" y="117" />
+        <di:waypoint x="690" y="117" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_123uagz_di" bpmnElement="Flow_123uagz">
+        <di:waypoint x="350" y="117" />
+        <di:waypoint x="390" y="117" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_02bjz2v_di" bpmnElement="Flow_02bjz2v">
+        <di:waypoint x="215" y="117" />
+        <di:waypoint x="250" y="117" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1rw8pwu_di" bpmnElement="Flow_1rw8pwu">
+        <di:waypoint x="1090" y="117" />
+        <di:waypoint x="1130" y="117" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+        <dc:Bounds x="179" y="99" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1cluqgp_di" bpmnElement="Activity_1cluqgp">
+        <dc:Bounds x="250" y="77" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ServiceTask_0iry5yw_di" bpmnElement="ServiceTask_0iry5yw">
+        <dc:Bounds x="540" y="77" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="CallActivity_1yilxx3_di" bpmnElement="CallActivity_1yilxx3">
+        <dc:Bounds x="690" y="77" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0wgjtoy_di" bpmnElement="Activity_0wgjtoy">
+        <dc:Bounds x="840" y="77" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0lulaof_di" bpmnElement="Activity_0lulaof">
+        <dc:Bounds x="990" y="77" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0g3dip7_di" bpmnElement="Activity_0g3dip7">
+        <dc:Bounds x="1130" y="77" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0fsaanz_di" bpmnElement="Activity_1vptrrr">
+        <dc:Bounds x="1270" y="77" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_14qdixj_di" bpmnElement="Event_14qdixj">
+        <dc:Bounds x="1432" y="99" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0qtgdm9_di" bpmnElement="Activity_0qtgdm9" isExpanded="true">
+        <dc:Bounds x="430" y="270" width="438" height="130" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="Flow_0anjylz_di" bpmnElement="Flow_0anjylz">
+        <di:waypoint x="680" y="333" />
+        <di:waypoint x="812" y="333" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_06q1m6i_di" bpmnElement="Flow_06q1m6i">
+        <di:waypoint x="488" y="333" />
+        <di:waypoint x="580" y="333" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="Event_08zcwc2_di" bpmnElement="Event_08zcwc2">
+        <dc:Bounds x="452" y="315" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="458" y="358" width="24" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_1wkm29u_di" bpmnElement="Event_1wkm29u">
+        <dc:Bounds x="812" y="315" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="822" y="357" width="19" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0ltxcii_di" bpmnElement="Activity_0ltxcii">
+        <dc:Bounds x="580" y="293" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_08pcuhq_di" bpmnElement="Activity_17vixcx">
+        <dc:Bounds x="390" y="77" width="100" height="80" />
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn:definitions>
diff --git a/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/MonitorSol003AdapterTerminateJobTaskTest.java b/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/MonitorSol003AdapterTerminateJobTaskTest.java
new file mode 100644 (file)
index 0000000..13fff6d
--- /dev/null
@@ -0,0 +1,148 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.workflow.engine.tasks;
+
+import com.google.gson.Gson;
+import org.camunda.bpm.engine.history.HistoricProcessInstance;
+import org.camunda.bpm.engine.history.HistoricVariableInstance;
+import org.camunda.bpm.engine.runtime.ProcessInstance;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.DeleteVnfResponse;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.BaseTest;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.json.GsonHttpMessageConverter;
+import org.springframework.test.web.client.MockRestServiceServer;
+import org.springframework.web.client.RestTemplate;
+import java.util.HashMap;
+import java.util.Map;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum.COMPLETED;
+import static org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum.PROCESSING;
+import static org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStatusRetrievalStatusEnum.STATUS_FOUND;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterConfiguration.SOL003_ADAPTER_REST_TEMPLATE_BEAN;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ *
+ */
+public class MonitorSol003AdapterTerminateJobTaskTest extends BaseTest {
+
+    private static final String MONITOR_SOL003_ADAPTER_TERMINATE_JOB_WORKFLOW = "MonitorSol003AdapterTerminateJob";
+
+    @Autowired
+    @Qualifier(SOL003_ADAPTER_REST_TEMPLATE_BEAN)
+    private RestTemplate restTemplate;
+
+    @Autowired
+    private GsonProvider gsonProvider;
+
+    private MockRestServiceServer mockRestServiceServer;
+    private Gson gson;
+
+    @Before
+    public void before() {
+        wireMockServer.resetAll();
+
+        final MockRestServiceServer.MockRestServiceServerBuilder builder = MockRestServiceServer.bindTo(restTemplate);
+        builder.ignoreExpectOrder(true);
+        mockRestServiceServer = builder.build();
+
+        gson = gsonProvider.getGson();
+        restTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson));
+    }
+
+
+    @Test
+    public void testMonitorSol003AdapterTerminateJobTaskWorkflow_SuccessfulCase() throws InterruptedException {
+        mockRestServiceServer.expect(requestTo(SOL003_ADAPTER_ENDPOINT_URL + "/jobs/" + RANDOM_JOB_ID))
+                .andExpect(method(HttpMethod.GET))
+                .andRespond(withSuccess(gson.toJson(getQueryJobResponse(COMPLETED)), MediaType.APPLICATION_JSON));
+
+        final ProcessInstance processInstance = executeWorkflow(MONITOR_SOL003_ADAPTER_TERMINATE_JOB_WORKFLOW,
+                RANDOM_JOB_ID, getVariables(RANDOM_JOB_ID, new DeleteVnfResponse().jobId(RANDOM_JOB_ID)));
+        assertTrue(waitForProcessInstanceToFinish(processInstance.getProcessInstanceId()));
+
+        final HistoricProcessInstance historicProcessInstance =
+                getHistoricProcessInstance(processInstance.getProcessInstanceId());
+        assertNotNull(historicProcessInstance);
+        assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
+
+        final HistoricVariableInstance nsResponseVariable = getVariable(processInstance.getProcessInstanceId(),
+                CamundaVariableNameConstants.OPERATION_STATUS_PARAM_NAME);
+        assertNotNull(nsResponseVariable);
+        assertEquals(COMPLETED, nsResponseVariable.getValue());
+    }
+
+    @Test
+    public void testMonitorSol003AdapterTerminateJobTaskWorkflow_SuccessfulCaseFollowingProcessingDelay()
+            throws InterruptedException {
+        mockRestServiceServer.expect(requestTo(SOL003_ADAPTER_ENDPOINT_URL + "/jobs/" + RANDOM_JOB_ID))
+                .andExpect(method(HttpMethod.GET))
+                .andRespond(withSuccess(gson.toJson(getQueryJobResponse(PROCESSING)), MediaType.APPLICATION_JSON));
+        mockRestServiceServer.expect(requestTo(SOL003_ADAPTER_ENDPOINT_URL + "/jobs/" + RANDOM_JOB_ID))
+                .andExpect(method(HttpMethod.GET))
+                .andRespond(withSuccess(gson.toJson(getQueryJobResponse(PROCESSING)), MediaType.APPLICATION_JSON));
+        mockRestServiceServer.expect(requestTo(SOL003_ADAPTER_ENDPOINT_URL + "/jobs/" + RANDOM_JOB_ID))
+                .andExpect(method(HttpMethod.GET))
+                .andRespond(withSuccess(gson.toJson(getQueryJobResponse(COMPLETED)), MediaType.APPLICATION_JSON));
+
+        final ProcessInstance processInstance = executeWorkflow(MONITOR_SOL003_ADAPTER_TERMINATE_JOB_WORKFLOW,
+                RANDOM_JOB_ID, getVariables(RANDOM_JOB_ID, new DeleteVnfResponse().jobId(RANDOM_JOB_ID)));
+        assertTrue(waitForProcessInstanceToFinish(processInstance.getProcessInstanceId()));
+
+        final HistoricProcessInstance historicProcessInstance =
+                getHistoricProcessInstance(processInstance.getProcessInstanceId());
+        assertNotNull(historicProcessInstance);
+        assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
+
+        final HistoricVariableInstance nsResponseVariable = getVariable(processInstance.getProcessInstanceId(),
+                CamundaVariableNameConstants.OPERATION_STATUS_PARAM_NAME);
+        assertNotNull(nsResponseVariable);
+        assertEquals(COMPLETED, nsResponseVariable.getValue());
+    }
+
+    private QueryJobResponse getQueryJobResponse(final OperationStateEnum operationState) {
+        return new QueryJobResponse().id(RANDOM_JOB_ID).operationState(operationState)
+                .operationStatusRetrievalStatus(STATUS_FOUND);
+    }
+
+    private Map<String, Object> getVariables(final String jobId, final DeleteVnfResponse deleteVnfResponse) {
+        final Map<String, Object> variables = new HashMap<>();
+        variables.put(CamundaVariableNameConstants.JOB_ID_PARAM_NAME, jobId);
+        variables.put(CamundaVariableNameConstants.DELETE_VNF_RESPONSE_PARAM_NAME, deleteVnfResponse);
+
+        return variables;
+    }
+
+}
diff --git a/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/TerminateNsTaskTest.java b/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/TerminateNsTaskTest.java
new file mode 100644 (file)
index 0000000..14e5b1c
--- /dev/null
@@ -0,0 +1,232 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.workflow.engine.tasks;
+
+import com.google.gson.Gson;
+import org.camunda.bpm.engine.history.HistoricProcessInstance;
+import org.hamcrest.text.MatchesPattern;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.DeleteVnfResponse;
+import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStatusRetrievalStatusEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.BaseTest;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.GsonProvider;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.NsRequestProcessingException;
+import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service.JobExecutorService;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoJob;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.OperationStateEnum;
+import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
+import org.onap.so.etsi.nfvo.ns.lcm.model.TerminateNsRequest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.json.GsonHttpMessageConverter;
+import org.springframework.test.web.client.MockRestServiceServer;
+import org.springframework.web.client.RestTemplate;
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+import static com.github.tomakehurst.wiremock.client.WireMock.delete;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.ok;
+import static com.github.tomakehurst.wiremock.client.WireMock.okJson;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogServiceProviderConfiguration.ETSI_CATALOG_REST_TEMPLATE_BEAN;
+import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.vnfm.Sol003AdapterConfiguration.SOL003_ADAPTER_REST_TEMPLATE_BEAN;
+import static org.springframework.test.web.client.ExpectedCount.times;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
+
+/**
+ * @author Andrew Lamb (andrew.a.lamb@est.tech)
+ *
+ */
+public class TerminateNsTaskTest extends BaseTest {
+
+    @Autowired
+    @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN)
+    private RestTemplate etsiCatalogRestTemplate;
+
+    @Autowired
+    @Qualifier(SOL003_ADAPTER_REST_TEMPLATE_BEAN)
+    private RestTemplate sol003AdapterRestTemplate;
+
+    private MockRestServiceServer mockEtsiCatalogRestServiceServer;
+
+    private MockRestServiceServer mockSol003AdapterRestServiceServer;
+
+    @Autowired
+    private JobExecutorService objUnderTest;
+
+    @Autowired
+    private GsonProvider gsonProvider;
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    private Gson gson;
+
+    @Before
+    public void before() {
+        wireMockServer.resetAll();
+        gson = gsonProvider.getGson();
+
+        mockEtsiCatalogRestServiceServer =
+                MockRestServiceServer.bindTo(etsiCatalogRestTemplate).ignoreExpectOrder(true).build();
+        mockSol003AdapterRestServiceServer =
+                MockRestServiceServer.bindTo(sol003AdapterRestTemplate).ignoreExpectOrder(true).build();
+
+        etsiCatalogRestTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson));
+        sol003AdapterRestTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson));
+
+    }
+
+    @After
+    public void after() {
+        wireMockServer.resetAll();
+        mockEtsiCatalogRestServiceServer.reset();
+    }
+
+    @Test
+    public void testRunTerminateNsJob_timeSetInTerminateRequest_throwsNsRequestProcessingException() {
+        final String nsInstanceId = UUID.randomUUID().toString();
+        final TerminateNsRequest terminateNsRequest = new TerminateNsRequest().terminationTime(LocalDateTime.now());
+        final String message = "TerminateNsRequest received with terminateTime: "
+                + terminateNsRequest.getTerminationTime()
+                + "\nOnly immediate Terminate requests are currently supported \n(i.e., terminateTime field must not be set).";
+        expectedException.expect(NsRequestProcessingException.class);
+        expectedException.expectMessage(message);
+        objUnderTest.runTerminateNsJob(nsInstanceId, terminateNsRequest);
+    }
+
+    @Test
+    public void testRunTerminateNsJob_NsInstNotInDb_throwsNsRequestProcessingException() {
+        final String nsInstanceId = UUID.randomUUID().toString();
+        final TerminateNsRequest terminateNsRequest = new TerminateNsRequest();
+        final String message = "No matching NS Instance for id: " + nsInstanceId + " found in database.";
+        assertThat(databaseServiceProvider.getNfvoNsInst(nsInstanceId)).isEmpty();
+        expectedException.expect(NsRequestProcessingException.class);
+        expectedException.expectMessage(message);
+        objUnderTest.runTerminateNsJob(nsInstanceId, terminateNsRequest);
+    }
+
+    @Test
+    public void testTerminateNsTask_SuccessfulCase() throws InterruptedException, IOException {
+        final String nsInstanceId = UUID.randomUUID().toString();
+        addDummyNsToDatabase(nsInstanceId);
+        mockSol003AdapterEndpoints();
+        mockAAIEndpoints();
+
+        final String nsLcmOpOccId = objUnderTest.runTerminateNsJob(nsInstanceId, new TerminateNsRequest());
+
+        final Optional<NfvoJob> optional = getJobByResourceId(nsInstanceId);
+        assertTrue(optional.isPresent());
+        final NfvoJob nfvoJob = optional.get();
+
+        // Confirm Process finishes in STATE_COMPLETED
+        assertTrue(waitForProcessInstanceToFinish(nfvoJob.getProcessInstanceId()));
+        final HistoricProcessInstance historicProcessInstance =
+                getHistoricProcessInstance(nfvoJob.getProcessInstanceId());
+        assertNotNull(historicProcessInstance);
+        assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
+
+        // Confirm NS Instance set to NOT_INSTANTIATED and related NF Instances Deleted
+        final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsInstanceId);
+        assertTrue(optionalNfvoNsInst.isPresent());
+        final NfvoNsInst nfvoNsInst = optionalNfvoNsInst.get();
+        assertEquals(State.NOT_INSTANTIATED, nfvoNsInst.getStatus());
+        final List<NfvoNfInst> nfvoNfInsts = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstanceId);
+        assertTrue(nfvoNfInsts.isEmpty());
+
+        // Confirm NS LCM OP OCC Job set to Completed
+        final Optional<NsLcmOpOcc> optionalNsLcmOpOcc = databaseServiceProvider.getNsLcmOpOcc(nsLcmOpOccId);
+        assertTrue(optionalNsLcmOpOcc.isPresent());
+        final NsLcmOpOcc nsLcmOpOcc = optionalNsLcmOpOcc.get();
+        assertEquals(OperationStateEnum.COMPLETED, nsLcmOpOcc.getOperationState());
+    }
+
+    private void addDummyNsToDatabase(final String nsInstanceId) {
+        final String nsPackageId = UUID.randomUUID().toString();
+        final NfvoNsInst nfvoNsInst =
+                new NfvoNsInst().nsInstId(nsInstanceId).name("nsName").nsPackageId(nsPackageId).nsdId("nsdId")
+                        .nsdInvariantId("nsdId").status(State.INSTANTIATED).statusUpdatedTime(LocalDateTime.now());
+        databaseServiceProvider.saveNfvoNsInst(nfvoNsInst);
+        addDummyNfToDatabase(nfvoNsInst);
+        addDummyNfToDatabase(nfvoNsInst);
+        addDummyNfToDatabase(nfvoNsInst);
+    }
+
+    private void addDummyNfToDatabase(final NfvoNsInst nfvoNsInst) {
+        final LocalDateTime localDateTime = LocalDateTime.now();
+        final String nfPackageId = UUID.randomUUID().toString();
+        final NfvoNfInst nfvoNfInst =
+                new NfvoNfInst().status(State.INSTANTIATED).createTime(localDateTime).lastUpdateTime(localDateTime)
+                        .name("nfName").vnfdId("vnfdId").packageId(nfPackageId).nfvoNsInst(nfvoNsInst);
+        databaseServiceProvider.saveNfvoNfInst(nfvoNfInst);
+    }
+
+    private void mockSol003AdapterEndpoints() {
+        final int numTimes = 3;
+
+        mockSol003AdapterRestServiceServer
+                .expect(times(numTimes),
+                        requestTo(MatchesPattern.matchesPattern(SOL003_ADAPTER_ENDPOINT_URL + "/vnfs/.*")))
+                .andExpect(method(HttpMethod.DELETE))
+                .andRespond(withSuccess(gson.toJson(new DeleteVnfResponse().jobId(UUID.randomUUID().toString())),
+                        MediaType.APPLICATION_JSON));
+
+        mockSol003AdapterRestServiceServer
+                .expect(times(numTimes),
+                        requestTo(MatchesPattern.matchesPattern(SOL003_ADAPTER_ENDPOINT_URL + "/jobs/.*")))
+                .andExpect(method(HttpMethod.GET))
+                .andRespond(withSuccess(gson.toJson(
+                        new org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse().operationState(
+                                org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum.COMPLETED)
+                                .operationStatusRetrievalStatus(OperationStatusRetrievalStatusEnum.STATUS_FOUND)),
+                        MediaType.APPLICATION_JSON));
+    }
+
+    private void mockAAIEndpoints() {
+        final String modelEndpoint = "/aai/v[0-9]+/network/generic-vnfs/generic-vnf/" + UUID_REGEX;
+        final String resourceVersion = "12345";
+
+        final String body =
+                "{\"resource-version\": \"" + resourceVersion + "\",\n\"orchestration-status\": \"Assigned\"}";
+        wireMockServer.stubFor(get(urlMatching(modelEndpoint)).willReturn(ok()).willReturn(okJson(body)));
+
+        wireMockServer.stubFor(
+                delete(urlMatching(modelEndpoint + "\\?resource-version=" + resourceVersion)).willReturn(ok()));
+    }
+
+}
index cb8f920..c47bbdb 100644 (file)
@@ -216,7 +216,7 @@ public class NsLcmOpOcc {
     @Override
     public String toString() {
         final StringBuilder sb = new StringBuilder();
-        sb.append("class NfvoNsInst {\n");
+        sb.append("class NsLcmOpOcc {\n");
         sb.append("    id: ").append(toIndentedString(id)).append("\n");
         sb.append("    operationState: ").append(toIndentedString(operationState)).append("\n");
         sb.append("    stateEnteredTime: ").append(toIndentedString(stateEnteredTime)).append("\n");
index 844f608..2d6d033 100644 (file)
@@ -27,7 +27,7 @@ import org.springframework.data.repository.CrudRepository;
  * @author Waqas Ikram (waqas.ikram@est.tech)
  *
  */
-public interface NfvoJobRepository extends CrudRepository<NfvoJob, String> {
+public interface NfvoJobRepository extends CrudRepository<NfvoJob, String>, RefreshableRepository<NfvoJob> {
 
     Optional<NfvoJob> findByResourceId(final String resourceId);
 
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/RefreshableRepository.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/RefreshableRepository.java
new file mode 100644 (file)
index 0000000..efa7130
--- /dev/null
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.database.repository;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public interface RefreshableRepository<T> {
+
+    void refreshEntity(T entity);
+
+}
diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/RefreshableRepositoryImpl.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-database-service/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/database/repository/RefreshableRepositoryImpl.java
new file mode 100644 (file)
index 0000000..abd095f
--- /dev/null
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.etsi.nfvo.ns.lcm.database.repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Repository
+public class RefreshableRepositoryImpl<T> implements RefreshableRepository<T> {
+
+    @PersistenceContext
+    private EntityManager entityManager;
+
+    @Override
+    public void refreshEntity(final T entity) {
+        entityManager.refresh(entity);
+
+    }
+
+}
index 3682425..1aaddeb 100644 (file)
@@ -33,6 +33,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * @author Waqas Ikram (waqas.ikram@est.tech)
@@ -71,6 +74,16 @@ public class DatabaseServiceProvider {
         return nfvoJobRepository.findById(jobId);
     }
 
+    @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.REPEATABLE_READ, readOnly = true)
+    public Optional<NfvoJob> getRefreshedJob(final String jobId) {
+        logger.info("Querying database for NfvoJob using jobId: {}", jobId);
+        final Optional<NfvoJob> optional = getJob(jobId);
+        if (optional.isPresent()) {
+            nfvoJobRepository.refreshEntity(optional.get());
+        }
+        return optional;
+    }
+
     public Optional<NfvoJob> getJobByResourceId(final String resourceId) {
         logger.info("Querying database for NfvoJob using resourceId: {}", resourceId);
         return nfvoJobRepository.findByResourceId(resourceId);
@@ -127,6 +140,16 @@ public class DatabaseServiceProvider {
         return nfvoNfInstRepository.findByNfInstId(nfInstId);
     }
 
+    public boolean isNfInstExists(final String nfInstId) {
+        logger.info("Checking if NfvoNfInst entry exists in database using nfInstId: {}", nfInstId);
+        return nfvoNfInstRepository.findByNfInstId(nfInstId).isPresent();
+    }
+
+    public void deleteNfvoNfInst(final String nfInstId) {
+        logger.info("Deleting NfvoNfInst with nfInstId: {} from database", nfInstId);
+        nfvoNfInstRepository.deleteById(nfInstId);
+    }
+
     public boolean addNSLcmOpOcc(final NsLcmOpOcc nsLcmOpOcc) {
         logger.info("Adding NSLcmOpOcc: {} to database", nsLcmOpOcc);
         return nsLcmOpOccRepository.save(nsLcmOpOcc) != null;
index 42579fd..8108749 100644 (file)
@@ -65,8 +65,12 @@ public class DatabaseServiceProviderTest {
                 .resourceName(DUMMY_NAME).startTime(CURRENT_DATE_TIME).status(JobStatusEnum.STARTED);
         databaseServiceProvider.addJob(expected);
 
-        final Optional<NfvoJob> actual = databaseServiceProvider.getJob(expected.getJobId());
+        Optional<NfvoJob> actual = databaseServiceProvider.getJob(expected.getJobId());
         assertEquals(expected, actual.get());
+
+        actual = databaseServiceProvider.getRefreshedJob(expected.getJobId());
+        assertEquals(expected, actual.get());
+
     }
 
     @Test
index da1649d..80ec604 100644 (file)
@@ -45,7 +45,7 @@ public class EtsiSoNsLcmManagerUrlProvider {
                 + nsInstanceId);
     }
 
-    public URI getInstantiatedOccUri(final String nsLcmOpOccId) {
+    public URI getNsLcmOpOccUri(final String nsLcmOpOccId) {
         return URI.create(etsiNsLcmManagerEndpoint + Constants.NS_LIFE_CYCLE_MANAGEMENT_BASE_URL + "/ns_lcm_op_occs/"
                 + nsLcmOpOccId);
     }
index 792ffdd..2ebf55f 100644 (file)
@@ -27,6 +27,7 @@ import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.service.JobExecutorService;
 import org.onap.so.etsi.nfvo.ns.lcm.model.CreateNsRequest;
 import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest;
 import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesNsInstance;
+import org.onap.so.etsi.nfvo.ns.lcm.model.TerminateNsRequest;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -70,8 +71,15 @@ public class NsLifeCycleManager {
                 instantiateNsRequest, nsInstanceId);
         final String nsLcmOpOccId = jobExecutorService.runInstantiateNsJob(nsInstanceId, instantiateNsRequest);
 
-        return etsiSoNsLcmManagerUrlProvider.getInstantiatedOccUri(nsLcmOpOccId);
+        return etsiSoNsLcmManagerUrlProvider.getNsLcmOpOccUri(nsLcmOpOccId);
 
     }
 
+    public URI terminateNs(final String nsInstanceId, final TerminateNsRequest terminateNsRequest) {
+        logger.info("Will execute Terminate Ns for TerminateNsRequest: {} and nsInstanceId: {}", terminateNsRequest,
+                nsInstanceId);
+        final String nsLcmOpOccId = jobExecutorService.runTerminateNsJob(nsInstanceId, terminateNsRequest);
+
+        return etsiSoNsLcmManagerUrlProvider.getNsLcmOpOccUri(nsLcmOpOccId);
+    }
 }
index 87ec842..cfda89f 100644 (file)
@@ -72,8 +72,9 @@ public class NsLifecycleManagementController {
      * @param globalCustomerId The global customer ID
      * @param serviceType The service type
      * @param createNsRequest create network service request (see clause 6.5.2.9)
-     * @return "201 Created" response containing a representation of the NS instance resource {@link NsInstance} just
-     *         created by the NFVO, and provides the URI of the newly-created resource in the "Location:" HTTP header
+     * @return "201 Created" response containing a representation of the NS instance resource
+     *         {@link NsInstancesNsInstance} just created by the NFVO, and provides the URI of the newly-created
+     *         resource in the "Location:" HTTP header
      */
     @PostMapping(value = "/ns_instances", produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML},
             consumes = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@@ -145,7 +146,10 @@ public class NsLifecycleManagementController {
     public ResponseEntity<?> terminateNs(@PathVariable("nsInstanceId") final String nsInstanceId,
             @RequestBody final TerminateNsRequest terminateNsRequest) {
         logger.debug("Received terminate NS request: {}\n with nsInstanceId: {}", terminateNsRequest, nsInstanceId);
-        return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).body("Operation is not supported yet");
+        final URI resourceUri = nsLifeCycleManager.terminateNs(nsInstanceId, terminateNsRequest);
+        logger.info("{} Ns Terminate started successfully. Resource Operation Occurrence uri: {}", nsInstanceId,
+                resourceUri);
+        return ResponseEntity.accepted().location(resourceUri).build();
     }
 
 }
index 81c4e8f..4b11952 100644 (file)
@@ -77,7 +77,7 @@ public class NsLifecycleManagementControllerTest {
     private static final String GLOBAL_CUSTOMER_ID = UUID.randomUUID().toString();
     private static final String EXPECTED_CREATE_REQ_LOCATION_URL =
             EXPECTED_BASE_URL + "/ns_instances/" + RANDOM_NS_INST_ID;
-    private static final String EXPECTED_INSTANTIATE_REQ_LOCATION_URL =
+    private static final String EXPECTED_NS_LCM_OP_OCC_REQ_LOCATION_URL =
             EXPECTED_BASE_URL + "/ns_lcm_op_occs/" + RANDOM_NS_LCM_OP_OCC_ID;
 
     @LocalServerPort
@@ -197,7 +197,7 @@ public class NsLifecycleManagementControllerTest {
         assertTrue(httpHeaders.containsKey(HttpHeaders.LOCATION));
         final List<String> actual = httpHeaders.get(HttpHeaders.LOCATION);
         assertEquals(1, actual.size());
-        assertEquals(EXPECTED_INSTANTIATE_REQ_LOCATION_URL, actual.get(0));
+        assertEquals(EXPECTED_NS_LCM_OP_OCC_REQ_LOCATION_URL, actual.get(0));
     }
 
     @Test
@@ -218,17 +218,43 @@ public class NsLifecycleManagementControllerTest {
     }
 
     @Test
-    public void testTerminateNs_ValidInstantiateNsRequest() {
-        final String baseUrl = getNsLcmBaseUrl() + "/ns_instances/" + UUID.randomUUID().toString() + "/terminate";
-        final HttpEntity<?> request = new HttpEntity<>(getTerminateNsRequest());
+    public void testTerminateNs_ValidTerminateNsRequest_Success() {
+        final TerminateNsRequest terminateNsRequest = getTerminateNsRequest();
+        when(mockedJobExecutorService.runTerminateNsJob(eq(RANDOM_NS_INST_ID), eq(terminateNsRequest)))
+                .thenReturn(RANDOM_NS_LCM_OP_OCC_ID);
+
+        final String baseUrl = getNsLcmBaseUrl() + "/ns_instances/" + RANDOM_NS_INST_ID + "/terminate";
+        final HttpEntity<?> request = new HttpEntity<>(terminateNsRequest);
         final ResponseEntity<Void> responseEntity =
                 testRestTemplate.exchange(baseUrl, HttpMethod.POST, request, Void.class);
-        assertEquals(HttpStatus.NOT_IMPLEMENTED, responseEntity.getStatusCode());
+        assertEquals(HttpStatus.ACCEPTED, responseEntity.getStatusCode());
+
+        final HttpHeaders httpHeaders = responseEntity.getHeaders();
+        assertTrue(httpHeaders.containsKey(HttpHeaders.LOCATION));
+        final List<String> actual = httpHeaders.get(HttpHeaders.LOCATION);
+        assertEquals(1, actual.size());
+        assertEquals(EXPECTED_NS_LCM_OP_OCC_REQ_LOCATION_URL, actual.get(0));
     }
 
+    @Test
+    public void testTerminateNs_ValidTerminateNsRequest_nsRequestProcessingExceptionThrown_returnInlineResponse400() {
+        final String errorMessage = "ERROR MESSAGE";
+        final TerminateNsRequest terminateNsRequest = getTerminateNsRequest();
+        when(mockedJobExecutorService.runTerminateNsJob(eq(RANDOM_NS_INST_ID), eq(terminateNsRequest)))
+                .thenThrow(new NsRequestProcessingException(errorMessage));
+
+        final String baseUrl = getNsLcmBaseUrl() + "/ns_instances/" + RANDOM_NS_INST_ID + "/terminate";
+        final HttpEntity<?> request = new HttpEntity<>(terminateNsRequest);
+        final ResponseEntity<InlineResponse400> responseEntity =
+                testRestTemplate.exchange(baseUrl, HttpMethod.POST, request, InlineResponse400.class);
+        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode());
+        assertTrue(responseEntity.hasBody());
+        assertNotNull(responseEntity.getBody());
+    }
 
     private TerminateNsRequest getTerminateNsRequest() {
-        return new TerminateNsRequest().terminationTime(LocalDateTime.now());
+        // Only support for the immediate Terminate request; i.e., terminateTime field is empty (not set)
+        return new TerminateNsRequest();
     }
 
     private InstantiateNsRequest getInstantiateNsRequest() {