Adding Termination AS 73/133173/1
authorwaqas.ikram <waqas.ikram@est.tech>
Tue, 7 Feb 2023 14:52:46 +0000 (14:52 +0000)
committerwaqas.ikram <waqas.ikram@est.tech>
Tue, 7 Feb 2023 14:52:54 +0000 (14:52 +0000)
Change-Id: I200d007b6d36d9df6d6f891cb247bb4ec17bc78a
Issue-ID: SO-4053
Signed-off-by: waqas.ikram <waqas.ikram@est.tech>
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/kubernetes/KubernetesClientImpl.java
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/MonitorHelmUnInstallStatusTask.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/TerminateAsTask.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/TerminateDeploymentItemRequest.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/TerminateDeploymentItemTask.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/resources/MonitorHelmUnInstallStatus.bpmn [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/resources/TerminateAs.bpmn [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/resources/TerminateDeploymentItem.bpmn [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/TerminateAsTaskTest.java [new file with mode: 0644]

index 15f6d83..06f0add 100644 (file)
@@ -709,20 +709,16 @@ public class KubernetesClientImpl implements KubernetesClient {
     private KubernetesResource getKubernetesResource(final String apiVersion, final String kind,
             final V1ObjectMeta metadata) {
         final GroupVersion groupVersion = GroupVersion.parse(apiVersion);
-        final KubernetesResource resource =
-                new KubernetesResource().id(metadata.getUid()).name(metadata.getName()).group(groupVersion.getGroup())
-                        .version(groupVersion.getVersion()).kind(kind).resourceVersion(metadata.getResourceVersion())
-                        .namespace(metadata.getNamespace() != null ? metadata.getNamespace() : "")
-                        .labels(getLabels(metadata.getLabels()));
-        return resource;
+        return new KubernetesResource().id(metadata.getUid()).name(metadata.getName()).group(groupVersion.getGroup())
+                .version(groupVersion.getVersion()).kind(kind).resourceVersion(metadata.getResourceVersion())
+                .namespace(metadata.getNamespace() != null ? metadata.getNamespace() : "")
+                .labels(getLabels(metadata.getLabels()));
     }
 
     private List<String> getLabels(final Map<String, String> labels) {
         if (labels != null) {
             final List<String> result = new ArrayList<>();
-            labels.entrySet().forEach(entry -> {
-                result.add(entry.getKey() + "=" + entry.getValue());
-            });
+            labels.entrySet().forEach(entry -> result.add(entry.getKey() + "=" + entry.getValue()));
             return result;
         }
         return Collections.emptyList();
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/MonitorHelmUnInstallStatusTask.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/MonitorHelmUnInstallStatusTask.java
new file mode 100644 (file)
index 0000000..3f2a1bd
--- /dev/null
@@ -0,0 +1,182 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.AS_DEPLOYMENT_ITEM_INST_ID_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.KIND_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.KUBE_CONFIG_FILE_PATH_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.KUBE_KINDS_RESULT_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.RELEASE_NAME_PARAM_NAME;
+
+import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.KIND_DAEMON_SET;
+import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.KIND_DEPLOYMENT;
+import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.KIND_JOB;
+import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.KIND_POD;
+import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.KIND_REPLICA_SET;
+import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.KIND_SERVICE;
+import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.KIND_STATEFUL_SET;
+
+import io.kubernetes.client.openapi.ApiClient;
+import java.util.Map;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.cnfm.lcm.bpmn.flows.exceptions.KubernetesRequestTimeOut;
+import org.onap.so.cnfm.lcm.bpmn.flows.extclients.kubernetes.KubernetesClient;
+import org.onap.so.cnfm.lcm.bpmn.flows.extclients.kubernetes.KubernetesClientProvider;
+import org.onap.so.cnfm.lcm.database.beans.JobStatusEnum;
+import org.onap.so.cnfm.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Raviteja Karumuri (raviteja.karumuri@est.tech)
+ */
+@Component
+public class MonitorHelmUnInstallStatusTask extends AbstractServiceTask {
+
+    private static final Logger logger = LoggerFactory.getLogger(MonitorHelmUnInstallStatusTask.class);
+    private static final int MAX_RETRIES = 10;
+    private static final String IS_RESOURCE_DELETED_PARAM_NAME = "isResourceDeleted";
+    private static final String RETRY_COUNTER_PARAM_NAME = "retryCounter";
+    private final KubernetesClientProvider kubernetesClientProvider;
+    private final KubernetesClient kubernetesClient;
+
+    @Autowired
+    protected MonitorHelmUnInstallStatusTask(final DatabaseServiceProvider databaseServiceProvider,
+            final KubernetesClientProvider kubernetesClientProvider, final KubernetesClient kubernetesClient) {
+        super(databaseServiceProvider);
+        this.kubernetesClientProvider = kubernetesClientProvider;
+        this.kubernetesClient = kubernetesClient;
+    }
+
+    public void updateJobStatus(final DelegateExecution execution) {
+        logger.info("Executing updateJobStatus ");
+        final String kind = (String) execution.getVariable(KIND_PARAM_NAME);
+        final String asDeploymentItemInstId = (String) execution.getVariable(AS_DEPLOYMENT_ITEM_INST_ID_PARAM_NAME);
+
+        addJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Checking if resource: " + kind
+                + " is terminated for asDeploymentItemInstId: " + asDeploymentItemInstId);
+
+        execution.setVariable(RETRY_COUNTER_PARAM_NAME, 0);
+
+        logger.info("Finished updateJobStatus ...");
+    }
+
+    public void isResourceDeleted(final DelegateExecution execution) {
+        logger.info("Executing isResourceDeleted ");
+        final String kind = (String) execution.getVariable(KIND_PARAM_NAME);
+        final String releaseName = (String) execution.getVariable(RELEASE_NAME_PARAM_NAME);
+        final String kubeConfigFile = (String) execution.getVariable(KUBE_CONFIG_FILE_PATH_PARAM_NAME);
+        final String labelSelector = "app.kubernetes.io/instance=" + releaseName;
+        try {
+            final ApiClient apiClient = kubernetesClientProvider.getApiClient(kubeConfigFile);
+            boolean isDeleted = false;
+            logger.debug("Will check if resource type: {} is Deleted using labelSelector: {}", kind, labelSelector);
+            switch (kind) {
+                case KIND_JOB:
+                    isDeleted = kubernetesClient.isJobDeleted(apiClient, labelSelector);
+                    break;
+                case KIND_POD:
+                    isDeleted = kubernetesClient.isPodDeleted(apiClient, labelSelector);
+                    break;
+                case KIND_SERVICE:
+                    isDeleted = kubernetesClient.isServiceDeleted(apiClient, labelSelector);
+                    break;
+                case KIND_DEPLOYMENT:
+                    isDeleted = kubernetesClient.isDeploymentDeleted(apiClient, labelSelector);
+                    break;
+                case KIND_REPLICA_SET:
+                    isDeleted = kubernetesClient.isReplicaSetDeleted(apiClient, labelSelector);
+                    break;
+                case KIND_DAEMON_SET:
+                    isDeleted = kubernetesClient.isDaemonSetDeleted(apiClient, labelSelector);
+                    break;
+                case KIND_STATEFUL_SET:
+                    isDeleted = kubernetesClient.isStatefulSetDeleted(apiClient, labelSelector);
+                    break;
+
+                default:
+                    logger.warn("Unknown resource type {} setting {} flag to true", kind,
+                            IS_RESOURCE_DELETED_PARAM_NAME);
+                    isDeleted = true;
+                    break;
+            }
+
+            logger.debug("Resource '{}' isDeleted: {}", kind, isDeleted);
+            execution.setVariable(IS_RESOURCE_DELETED_PARAM_NAME, isDeleted);
+
+        } catch (final KubernetesRequestTimeOut kubernetesRequestTimeOut) {
+            final Integer counter = (Integer) execution.getVariable(RETRY_COUNTER_PARAM_NAME);
+            if (counter > MAX_RETRIES) {
+                final String message = "Retries max out for resource: " + kind;
+                logger.error(message);
+                abortOperation(execution, message);
+            }
+            logger.debug("Current retries counter: {} will increament and try again", counter);
+            execution.setVariable(RETRY_COUNTER_PARAM_NAME, counter + 1);
+            execution.setVariable(IS_RESOURCE_DELETED_PARAM_NAME, false);
+
+        } catch (final Exception exception) {
+            final String message = "Unable to preform delete status check for resource " + kind;
+            logger.error(message, exception);
+            abortOperation(execution, message);
+        }
+        logger.info("Finished isResourceDeleted ...");
+
+    }
+
+    public void checkIfOperationWasSuccessful(final DelegateExecution execution) {
+        logger.info("Executing checkIfOperationWasSuccessful ");
+
+        final String kind = (String) execution.getVariable(KIND_PARAM_NAME);
+
+        @SuppressWarnings("unchecked")
+        final Map<String, Boolean> kubeKindResult =
+                (Map<String, Boolean>) execution.getVariable(KUBE_KINDS_RESULT_PARAM_NAME);
+
+        final boolean isDeleted = (boolean) execution.getVariable(IS_RESOURCE_DELETED_PARAM_NAME);
+        logger.debug("{} delete status {}", kind, isDeleted ? "Successful" : "failed");
+        kubeKindResult.put(kind, isDeleted);
+
+        execution.setVariable(KUBE_KINDS_RESULT_PARAM_NAME, kubeKindResult);
+
+        if (!isDeleted) {
+            final String message = "Status check failed for resource: {}" + kind;
+            logger.error(message);
+            abortOperation(execution, message);
+        }
+
+        final String asDeploymentItemInstId = (String) execution.getVariable(AS_DEPLOYMENT_ITEM_INST_ID_PARAM_NAME);
+        addJobStatus(execution, JobStatusEnum.IN_PROGRESS,
+                "Resource " + kind + " is deleting for asDeploymentItemInstId: " + asDeploymentItemInstId);
+        logger.info("Finished checkIfOperationWasSuccessful ...");
+    }
+
+    public void timeOutLogFailue(final DelegateExecution execution) {
+        logger.info("Executing timeOutLogFailue ");
+        final String message = "Is Resource Deleted operation timed out";
+        logger.error(message);
+        abortOperation(execution, message);
+        logger.info("Finished timeOutLogFailue ...");
+    }
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/TerminateAsTask.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/TerminateAsTask.java
new file mode 100644 (file)
index 0000000..d834c4d
--- /dev/null
@@ -0,0 +1,208 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.AS_INSTANCE_ID_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.DEPLOYMENT_ITEM_TERMINATE_REQUESTS;
+import static org.onap.so.cnfm.lcm.database.beans.JobStatusEnum.FINISHED;
+import static org.onap.so.cnfm.lcm.database.beans.JobStatusEnum.IN_PROGRESS;
+import static org.onap.so.cnfm.lcm.database.beans.JobStatusEnum.STARTED;
+
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.beans.nsmf.OrchestrationStatusEnum;
+import org.onap.so.cnfm.lcm.bpmn.flows.exceptions.KubeConfigFileNotFoundException;
+import org.onap.so.cnfm.lcm.bpmn.flows.extclients.aai.AaiServiceProvider;
+import org.onap.so.cnfm.lcm.bpmn.flows.service.KubConfigProvider;
+import org.onap.so.cnfm.lcm.database.beans.AsDeploymentItem;
+import org.onap.so.cnfm.lcm.database.beans.AsInst;
+import org.onap.so.cnfm.lcm.database.beans.State;
+import org.onap.so.cnfm.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Component
+public class TerminateAsTask extends AbstractServiceTask {
+    private static final Logger logger = LoggerFactory.getLogger(TerminateAsTask.class);
+    private final KubConfigProvider kubConfigProvider;
+    private final AaiServiceProvider aaiServiceProvider;
+    private static final String KUBE_CONFIG_FILE_PARAM_NAME = "kubeConfigFile";
+    private static final String IS_AS_TERMINATION_SUCCESSFUL_PARAM_NAME = "isAsTerminationSuccessful";
+
+    @Autowired
+    protected TerminateAsTask(final DatabaseServiceProvider databaseServiceProvider,
+                              final KubConfigProvider kubConfigProvider, final AaiServiceProvider aaiServiceProvider) {
+        super(databaseServiceProvider);
+        this.kubConfigProvider = kubConfigProvider;
+        this.aaiServiceProvider = aaiServiceProvider;
+    }
+
+    public void setJobStatusToStarted(final DelegateExecution execution) {
+        setJobStatus(execution, STARTED, "Terminate AS workflow process started");
+    }
+
+    public void setJobStatusToFinished(final DelegateExecution execution) {
+        setJobStatus(execution, FINISHED, "Terminate AS workflow process finished");
+    }
+
+    public void setJobStatusToError(final DelegateExecution execution) {
+        setJobStatusToError(execution, "Terminate AS workflow process failed");
+    }
+
+    public void updateAsInstanceStatusToTerminating(final DelegateExecution execution) {
+        logger.info("Executing updateAsInstanceStatusToTerminating");
+        setJobStatus(execution, IN_PROGRESS, "Updating AsInst Status to " + State.TERMINATING);
+        updateAsInstanceStatus(execution, State.TERMINATING);
+        logger.info("Finished executing updateAsInstanceStatusToTerminating  ...");
+    }
+
+    public void updateAsInstanceStatusToNotInstantiated(final DelegateExecution execution) {
+        logger.info("Executing updateAsInstanceStatusToNotInstantiated");
+        setJobStatus(execution, IN_PROGRESS, "Updating AsInst Status to " + State.NOT_INSTANTIATED);
+        updateAsInstanceStatus(execution, State.NOT_INSTANTIATED);
+        logger.info("Finished executing updateAsInstanceStatusToNotInstantiated  ...");
+    }
+
+    public void logTimeOut(final DelegateExecution execution) {
+        logger.error("Deployment items Termination timedOut ...");
+        final String asInstId = (String) execution.getVariable(AS_INSTANCE_ID_PARAM_NAME);
+        final List<AsDeploymentItem> asDeploymentItems =
+                databaseServiceProvider.getAsDeploymentItemByAsInstId(asInstId);
+        if (asDeploymentItems != null) {
+            asDeploymentItems.stream().forEach(asDeploymentItem -> {
+                logger.info("Current status {} of terminating asDeploymentItem: {}", asDeploymentItem.getStatus(),
+                        asDeploymentItem.getName());
+            });
+        }
+    }
+
+    public void checkifKubConfigFileAvailable(final DelegateExecution execution) {
+        logger.info("Executing checkifKubConfigFileAvailable");
+        try {
+            setJobStatus(execution, IN_PROGRESS, "Checking if kubeconfig file is available or not");
+            final AsInst asInst = getAsInst(execution);
+
+            final Path kubeConfigFile = kubConfigProvider.getKubeConfigFile(asInst.getCloudOwner(),
+                    asInst.getCloudRegion(), asInst.getTenantId());
+
+            execution.setVariable(KUBE_CONFIG_FILE_PARAM_NAME, kubeConfigFile.toString());
+
+        } catch (final KubeConfigFileNotFoundException exception) {
+            final String message = "Unable to find kube-config file on filesystem";
+            logger.error(message, exception);
+            abortOperation(execution, message);
+
+        }
+
+        logger.info("Finished executing checkifKubConfigFileAvailable  ...");
+
+    }
+
+    public void prepareTerminateDeploymentItemRequests(final DelegateExecution execution) {
+        logger.info("Executing prepareTerminateDeploymentItemRequests ...");
+        setJobStatus(execution, IN_PROGRESS, "Preparing TerminateDeploymentItemRequest requests");
+
+        final String asInstId = (String) execution.getVariable(AS_INSTANCE_ID_PARAM_NAME);
+        final String kubeConfigFile = (String) execution.getVariable(KUBE_CONFIG_FILE_PARAM_NAME);
+
+        final List<AsDeploymentItem> asDeploymentItems =
+                databaseServiceProvider.getAsDeploymentItemByAsInstId(asInstId);
+
+        final Set<TerminateDeploymentItemRequest> requests = new TreeSet<>();
+
+        asDeploymentItems.forEach(asDeploymentItem -> {
+
+            final String asDeploymentItemInstId = asDeploymentItem.getAsDeploymentItemInstId();
+
+            final TerminateDeploymentItemRequest terminatedeploymentitemrequest = new TerminateDeploymentItemRequest();
+            terminatedeploymentitemrequest.setAsInstId(asInstId);
+            terminatedeploymentitemrequest.setAsDeploymentItemInstId(asDeploymentItemInstId);
+            terminatedeploymentitemrequest.setDeploymentOrder(asDeploymentItem.getDeploymentOrder());
+            terminatedeploymentitemrequest.setKubeConfigFile(kubeConfigFile);
+            terminatedeploymentitemrequest.setReleaseName(asDeploymentItem.getReleaseName());
+
+            requests.add(terminatedeploymentitemrequest);
+
+        });
+
+        execution.setVariable(DEPLOYMENT_ITEM_TERMINATE_REQUESTS, requests);
+
+        logger.info("Finished executing prepareTerminateDeploymentItemRequests ...");
+    }
+
+    public void checkIfDeploymentItemsTerminationWasSuccessful(final DelegateExecution execution) {
+        logger.info("Executing checkIfDeploymentItemsTerminationWasSuccessful");
+
+        @SuppressWarnings("unchecked")
+        final Set<TerminateDeploymentItemRequest> requests =
+                (Set<TerminateDeploymentItemRequest>) execution.getVariable(DEPLOYMENT_ITEM_TERMINATE_REQUESTS);
+
+        final String asInstId = (String) execution.getVariable(AS_INSTANCE_ID_PARAM_NAME);
+        final List<AsDeploymentItem> asDeploymentItems =
+                databaseServiceProvider.getAsDeploymentItemByAsInstId(asInstId);
+
+
+        if (asDeploymentItems == null || asDeploymentItems.isEmpty()) {
+            final String message = "Found empty asDeploymentItems";
+            abortOperation(execution, message);
+        } else if (requests.size() != asDeploymentItems.size()) {
+            final String message = "Missing asDeploymentItems. Request triggered has: " + requests.size()
+                    + " asDeploymentItems but database has: " + asDeploymentItems.size();
+            abortOperation(execution, message);
+        } else {
+            execution.setVariable(IS_AS_TERMINATION_SUCCESSFUL_PARAM_NAME, true);
+            asDeploymentItems.forEach(asDeploymentItem -> {
+                logger.info("Checking AsDeploymentItem {} termination status: {}",
+                        asDeploymentItem.getAsDeploymentItemInstId(), asDeploymentItem.getStatus());
+                if (!State.NOT_INSTANTIATED.equals(asDeploymentItem.getStatus())) {
+                    logger.error("AsDeploymentItem : {} {} termination failed",
+                            asDeploymentItem.getAsDeploymentItemInstId(), asDeploymentItem.getName());
+                    execution.setVariable(IS_AS_TERMINATION_SUCCESSFUL_PARAM_NAME, false);
+                }
+            });
+        }
+        logger.info("Finished executing checkIfDeploymentItemsTerminationWasSuccessful  ...");
+    }
+
+    public void updateGenericVnfStatustoDeActivated(final DelegateExecution execution) {
+
+        logger.debug("Executing updateGenericVnfStatustoDeActivated");
+        final String asInstId = (String) execution.getVariable(AS_INSTANCE_ID_PARAM_NAME);
+        final boolean result = aaiServiceProvider.updateGenericVnfStatus(asInstId,
+                OrchestrationStatusEnum.DEACTIVATED);
+        if (!result) {
+            abortOperation(execution, "Failed to update GenericVnf status to Deactivated as there"
+                    + "is no GenericVnf Found in AAI of ID: " + asInstId);
+        }
+        logger.info("Finished updating vnf status to Deactivated");
+    }
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/TerminateDeploymentItemRequest.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/TerminateDeploymentItemRequest.java
new file mode 100644 (file)
index 0000000..b4fb233
--- /dev/null
@@ -0,0 +1,122 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.cnfm.lcm.database.beans.utils.Utils.toIndentedString;
+
+import java.io.Serializable;
+import java.util.Comparator;
+import java.util.Objects;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ *
+ * @author Raviteja Karumuri (raviteja.karumuri@est.tech)
+ *
+ */
+public class TerminateDeploymentItemRequest implements Serializable, Comparable<TerminateDeploymentItemRequest> {
+
+    private static final long serialVersionUID = 2953758424937589468L;
+    private String asInstId;
+    private String asDeploymentItemInstId;
+    private String kubeConfigFile;
+    private Integer deploymentOrder;
+    private String releaseName;
+
+    private static final Comparator<Integer> COMPARATOR = Comparator.nullsFirst(Integer::compare).reversed();
+
+    public String getAsInstId() {
+        return asInstId;
+    }
+
+    public void setAsInstId(final String asInstId) {
+        this.asInstId = asInstId;
+    }
+
+    public String getAsDeploymentItemInstId() {
+        return asDeploymentItemInstId;
+    }
+
+    public void setAsDeploymentItemInstId(final String asDeploymentItemInstId) {
+        this.asDeploymentItemInstId = asDeploymentItemInstId;
+    }
+
+    public String getKubeConfigFile() {
+        return kubeConfigFile;
+    }
+
+    public void setKubeConfigFile(final String kubeConfigFile) {
+        this.kubeConfigFile = kubeConfigFile;
+    }
+
+    public Integer getDeploymentOrder() {
+        return deploymentOrder;
+    }
+
+    public void setDeploymentOrder(final Integer deploymentOrder) {
+        this.deploymentOrder = deploymentOrder;
+    }
+
+    public String getReleaseName() {
+        return releaseName;
+    }
+
+    public void setReleaseName(final String releaseName) {
+        this.releaseName = releaseName;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj instanceof TerminateDeploymentItemRequest) {
+            final TerminateDeploymentItemRequest that = (TerminateDeploymentItemRequest) obj;
+            return Objects.equals(asInstId, that.asInstId)
+                    && Objects.equals(asDeploymentItemInstId, that.asDeploymentItemInstId)
+                    && Objects.equals(kubeConfigFile, that.kubeConfigFile)
+                    && Objects.equals(deploymentOrder, that.deploymentOrder)
+                    && Objects.equals(releaseName, that.releaseName);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(asInstId, asDeploymentItemInstId, kubeConfigFile, deploymentOrder,
+                releaseName);
+    }
+
+    @Override
+    public int compareTo(@NotNull final TerminateDeploymentItemRequest terminateDeploymentItemRequest) {
+        return COMPARATOR.compare(this.getDeploymentOrder(), terminateDeploymentItemRequest.getDeploymentOrder());
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("class TerminateDeploymentItemRequest {\n");
+        sb.append("    asInstId: ").append(toIndentedString(asInstId)).append("\n");
+        sb.append("    asDeploymentItemInstId: ").append(toIndentedString(asDeploymentItemInstId)).append("\n");
+        sb.append("    deploymentOrder: ").append(toIndentedString(deploymentOrder)).append("\n");
+        sb.append("    kubeConfigFile: ").append(toIndentedString(kubeConfigFile)).append("\n");
+        sb.append("    releaseName: ").append(toIndentedString(releaseName)).append("\n");
+        sb.append("}");
+        return sb.toString();
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/TerminateDeploymentItemTask.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/TerminateDeploymentItemTask.java
new file mode 100644 (file)
index 0000000..e78f8f0
--- /dev/null
@@ -0,0 +1,198 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.tasks;
+
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.AS_DEPLOYMENT_ITEM_INST_ID_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.KUBE_CONFIG_FILE_PATH_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.KUBE_KINDS_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.KUBE_KINDS_RESULT_PARAM_NAME;
+import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.RELEASE_NAME_PARAM_NAME;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.onap.so.cnfm.lcm.bpmn.flows.extclients.aai.AaiServiceProvider;
+import org.onap.so.cnfm.lcm.bpmn.flows.extclients.helm.HelmClient;
+import org.onap.so.cnfm.lcm.bpmn.flows.extclients.kubernetes.KubernetesClientProvider;
+import org.onap.so.cnfm.lcm.bpmn.flows.extclients.kubernetes.KubernetesResource;
+import org.onap.so.cnfm.lcm.database.beans.AsInst;
+import org.onap.so.cnfm.lcm.database.beans.JobStatusEnum;
+import org.onap.so.cnfm.lcm.database.beans.State;
+import org.onap.so.cnfm.lcm.database.service.DatabaseServiceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ *
+ * @author Raviteja karumuri (raviteja.karumuri@est.tech)
+ *
+ */
+
+@Component
+public class TerminateDeploymentItemTask extends AbstractServiceTask {
+
+    private static final Logger logger = LoggerFactory.getLogger(TerminateDeploymentItemTask.class);
+
+    private static final String IS_DELETED_PARAM_NAME = "isDeleted";
+    private static final String TERMINATE_REQUEST_PARAM_NAME = "request";
+
+    private final AaiServiceProvider aaiServiceProvider;
+    private final HelmClient helmClient;
+    private final KubernetesClientProvider kubernetesClientProvider;
+
+    @Autowired
+    protected TerminateDeploymentItemTask(final DatabaseServiceProvider databaseServiceProvider,
+            final AaiServiceProvider aaiServiceProvider, final HelmClient helmClient,
+            final KubernetesClientProvider kubernetesClientProvider) {
+        super(databaseServiceProvider);
+        this.aaiServiceProvider = aaiServiceProvider;
+        this.helmClient = helmClient;
+        this.kubernetesClientProvider = kubernetesClientProvider;
+    }
+
+    public void checkIfDeploymentItemExistsInDb(final DelegateExecution execution) {
+        logger.info("Executing checkIfDeploymentItemExistsInDb");
+        final TerminateDeploymentItemRequest request =
+                (TerminateDeploymentItemRequest) execution.getVariable(TERMINATE_REQUEST_PARAM_NAME);
+        logger.info("Terminate request: {}", request);
+
+        final String asDeploymentItemInstId = request.getAsDeploymentItemInstId();
+        addJobStatus(execution, JobStatusEnum.IN_PROGRESS,
+                "Checking if Deployment item record exists in database for asDeploymentItemInstId: "
+                        + asDeploymentItemInstId);
+
+        if (!databaseServiceProvider.isAsDeploymentItemExists(request.getAsDeploymentItemInstId())) {
+            abortOperation(execution, "Deployment Item does not exists in database for asDeploymentItemInstId: "
+                    + asDeploymentItemInstId);
+        }
+        execution.setVariable(AS_DEPLOYMENT_ITEM_INST_ID_PARAM_NAME, request.getAsDeploymentItemInstId());
+        execution.setVariable(KUBE_CONFIG_FILE_PATH_PARAM_NAME, request.getKubeConfigFile());
+        logger.info("Finished executing checkIfDeploymentItemExistsInDb  ...");
+
+    }
+
+    public void unInstantiateHelmChart(final DelegateExecution execution) {
+        logger.info("Executing unInstantiateHelmChart");
+
+        final TerminateDeploymentItemRequest request =
+                (TerminateDeploymentItemRequest) execution.getVariable(TERMINATE_REQUEST_PARAM_NAME);
+        final String releaseName = request.getReleaseName();
+
+        try {
+            final Path kubeConfigFilePath = Paths.get(request.getKubeConfigFile());
+            helmClient.unInstallHelmChart(releaseName, kubeConfigFilePath);
+        } catch (final Exception exception) {
+            final String message = "Failed to uninstall helm chart: " + " using kube-config file: "
+                    + request.getKubeConfigFile() + "for reason: " + exception.getMessage();
+            logger.error(message, exception);
+            abortOperation(execution, message);
+        }
+        logger.info("Finished executing unInstantiateHelmChart  ...");
+
+    }
+
+
+    public void updateDeploymentItemStatusToNotInstantiated(final DelegateExecution execution) {
+
+        logger.info("Executing updateDeploymentItemStatusToNotInstantiated");
+        final TerminateDeploymentItemRequest request =
+                (TerminateDeploymentItemRequest) execution.getVariable(TERMINATE_REQUEST_PARAM_NAME);
+
+        updateDeploymentItemStatus(execution, request.getAsDeploymentItemInstId(), State.NOT_INSTANTIATED);
+
+        addJobStatus(execution, JobStatusEnum.FINISHED, "Successfully Terminated Deployment Item with "
+                + "releaseName: " + request.getReleaseName() + " and will set status to " + State.NOT_INSTANTIATED);
+
+        logger.info("Finished executing updateDeploymentItemStatusToNotInstantiated  ...");
+    }
+
+    public void getKubeKindsUsingManifestCommand(final DelegateExecution execution) {
+
+        logger.info("Executing getKubeKindsFromReleaseHistory");
+
+        final TerminateDeploymentItemRequest request =
+                (TerminateDeploymentItemRequest) execution.getVariable(TERMINATE_REQUEST_PARAM_NAME);
+        final String releaseName = request.getReleaseName();
+        final Path kubeConfigFilePath = Paths.get(request.getKubeConfigFile());
+        final Map<String, Boolean> kubeKindsMap = new HashMap<>();
+        final List<String> kinds = helmClient.getKubeKindsUsingManifestCommand(releaseName, kubeConfigFilePath);
+        if (kinds.isEmpty()) {
+            abortOperation(execution,
+                    "Unable to retrieve kinds from helm release history for releaseName: " + releaseName);
+        }
+        kinds.forEach(kind -> kubeKindsMap.put(kind, false));
+
+        execution.setVariable(RELEASE_NAME_PARAM_NAME, releaseName);
+        execution.setVariable(KUBE_KINDS_RESULT_PARAM_NAME, kubeKindsMap);
+        execution.setVariable(KUBE_KINDS_PARAM_NAME, kinds);
+    }
+
+    public void checkIfHelmUnInstallWasSuccessful(final DelegateExecution execution) {
+        logger.info("Executing checkIfHelmUnInstallWasSuccessful");
+
+        @SuppressWarnings("unchecked")
+        final Map<String, Boolean> kubeKindResult =
+                (Map<String, Boolean>) execution.getVariable(KUBE_KINDS_RESULT_PARAM_NAME);
+
+        execution.setVariable(IS_DELETED_PARAM_NAME, true);
+
+        kubeKindResult.forEach((key, value) -> {
+            logger.info("Checking if resource type {} was deleted Status: {}", key, value);
+
+            if (Boolean.FALSE.equals(value)) {
+                logger.error("resource type {} failed to delete", key);
+                execution.setVariable(IS_DELETED_PARAM_NAME, false);
+            }
+        });
+
+        final String kubeConfigFile = (String) execution.getVariable(KUBE_CONFIG_FILE_PATH_PARAM_NAME);
+        kubernetesClientProvider.closeApiClient(kubeConfigFile);
+
+        logger.info("Finished executing checkIfHelmUnInstallWasSuccessful  ...");
+
+    }
+
+    public void deleteK8ResourcesinAAI(final DelegateExecution execution) {
+        logger.info("Executing deleteK8ResourcesinAai");
+        final TerminateDeploymentItemRequest request =
+                (TerminateDeploymentItemRequest) execution.getVariable(TERMINATE_REQUEST_PARAM_NAME);
+        final List<KubernetesResource> resources =
+                aaiServiceProvider.getK8sResources(request.getAsInstId(), request.getAsDeploymentItemInstId());
+        final AsInst asInst = getAsInst(execution);
+        resources.forEach(resource -> aaiServiceProvider.deleteK8SResource(resource.getId(), asInst.getCloudOwner(),
+                asInst.getCloudRegion(), asInst.getTenantId()));
+    }
+
+    public void deleteVFModuleinAai(final DelegateExecution execution) {
+        logger.info("Executing deleteVFModuleinAai");
+
+        final TerminateDeploymentItemRequest request =
+                (TerminateDeploymentItemRequest) execution.getVariable(TERMINATE_REQUEST_PARAM_NAME);
+        aaiServiceProvider.deleteVfModule(request.getAsInstId(), request.getAsDeploymentItemInstId());
+        logger.info("Delete VfModule in AAi is Done");
+
+    }
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/resources/MonitorHelmUnInstallStatus.bpmn b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/resources/MonitorHelmUnInstallStatus.bpmn
new file mode 100644 (file)
index 0000000..8ea258e
--- /dev/null
@@ -0,0 +1,172 @@
+<?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:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1ln6j64" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.12.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">
+  <bpmn:process id="MonitorHelmUnInstallStatus" name="MonitorHelmUnInstallStatus" isExecutable="true">
+    <bpmn:endEvent id="helm_uninstall_Event_0v9a531">
+      <bpmn:incoming>helm_uninstall_Flow_1f87oz7</bpmn:incoming>
+    </bpmn:endEvent>
+    <bpmn:subProcess id="Activity_1exvnm9" name="${kindFromReleaseHistory}">
+      <bpmn:incoming>Flow_0f5dibe</bpmn:incoming>
+      <bpmn:outgoing>helm_uninstall_Flow_1kpnioc</bpmn:outgoing>
+      <bpmn:startEvent id="helm_uninstall_Event_1m6vi78">
+        <bpmn:outgoing>helm_uninstall_Flow_1kekeh7</bpmn:outgoing>
+      </bpmn:startEvent>
+      <bpmn:exclusiveGateway id="helm_uninstall_Gateway_0neju2q" default="helm_uninstall_Flow_1g3xchu">
+        <bpmn:incoming>helm_uninstall_Flow_0kdhub4</bpmn:incoming>
+        <bpmn:outgoing>helm_uninstall_Flow_1g3xchu</bpmn:outgoing>
+        <bpmn:outgoing>helm_uninstall_Flow_0n6qu57</bpmn:outgoing>
+      </bpmn:exclusiveGateway>
+      <bpmn:intermediateCatchEvent id="helm_uninstall_Event_0lx9pd7" name="Wait between checks" camunda:asyncAfter="true">
+        <bpmn:incoming>helm_uninstall_Flow_1g3xchu</bpmn:incoming>
+        <bpmn:outgoing>helm_uninstall_Flow_0tqwb9b</bpmn:outgoing>
+        <bpmn:timerEventDefinition id="TimerEventDefinition_1icke43">
+          <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT15S</bpmn:timeDuration>
+        </bpmn:timerEventDefinition>
+      </bpmn:intermediateCatchEvent>
+      <bpmn:endEvent id="helm_uninstall_Event_1pka4w4">
+        <bpmn:incoming>helm_uninstall_Flow_0n6qu57</bpmn:incoming>
+      </bpmn:endEvent>
+      <bpmn:serviceTask id="helm_uninstall_Activity_0rxj50o" name="&#10;Is Resource Deleted&#10;" camunda:asyncAfter="true" camunda:expression="${MonitorHelmUnInstallStatusTask.isResourceDeleted(execution)}">
+        <bpmn:incoming>helm_uninstall_Flow_11mzqci</bpmn:incoming>
+        <bpmn:incoming>helm_uninstall_Flow_0tqwb9b</bpmn:incoming>
+        <bpmn:outgoing>helm_uninstall_Flow_0kdhub4</bpmn:outgoing>
+      </bpmn:serviceTask>
+      <bpmn:serviceTask id="helm_uninstall_Activity_1cc0pq6" name="Update Job Status" camunda:expression="${MonitorHelmUnInstallStatusTask.updateJobStatus(execution)}">
+        <bpmn:incoming>helm_uninstall_Flow_1kekeh7</bpmn:incoming>
+        <bpmn:outgoing>helm_uninstall_Flow_11mzqci</bpmn:outgoing>
+      </bpmn:serviceTask>
+      <bpmn:sequenceFlow id="helm_uninstall_Flow_11mzqci" sourceRef="helm_uninstall_Activity_1cc0pq6" targetRef="helm_uninstall_Activity_0rxj50o" />
+      <bpmn:sequenceFlow id="helm_uninstall_Flow_1kekeh7" sourceRef="helm_uninstall_Event_1m6vi78" targetRef="helm_uninstall_Activity_1cc0pq6" />
+      <bpmn:sequenceFlow id="helm_uninstall_Flow_0tqwb9b" sourceRef="helm_uninstall_Event_0lx9pd7" targetRef="helm_uninstall_Activity_0rxj50o" />
+      <bpmn:sequenceFlow id="helm_uninstall_Flow_1g3xchu" sourceRef="helm_uninstall_Gateway_0neju2q" targetRef="helm_uninstall_Event_0lx9pd7" />
+      <bpmn:sequenceFlow id="helm_uninstall_Flow_0n6qu57" sourceRef="helm_uninstall_Gateway_0neju2q" targetRef="helm_uninstall_Event_1pka4w4">
+        <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{isResourceDeleted}</bpmn:conditionExpression>
+      </bpmn:sequenceFlow>
+      <bpmn:sequenceFlow id="helm_uninstall_Flow_0kdhub4" sourceRef="helm_uninstall_Activity_0rxj50o" targetRef="helm_uninstall_Gateway_0neju2q" />
+    </bpmn:subProcess>
+    <bpmn:endEvent id="helm_uninstall_Event_119znxi" name="Timeout Exception">
+      <bpmn:incoming>helm_uninstall_Flow_0qm63h0</bpmn:incoming>
+      <bpmn:terminateEventDefinition id="TerminateEventDefinition_14qywzg" />
+    </bpmn:endEvent>
+    <bpmn:serviceTask id="helm_uninstall_Activity_09s0jak" name="&#10;Time Out Log Failure&#10;" camunda:asyncAfter="true" camunda:expression="${MonitorHelmUnInstallStatusTask.timeOutLogFailue(execution)}">
+      <bpmn:incoming>helm_uninstall_Flow_1719q6v</bpmn:incoming>
+      <bpmn:outgoing>helm_uninstall_Flow_0qm63h0</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:serviceTask id="helm_uninstall_Activity_0a4jpkd" name="&#10;Check if operation was successful&#10;" camunda:asyncAfter="true" camunda:expression="${MonitorHelmUnInstallStatusTask.checkIfOperationWasSuccessful(execution)}">
+      <bpmn:incoming>helm_uninstall_Flow_1kpnioc</bpmn:incoming>
+      <bpmn:outgoing>helm_uninstall_Flow_1f87oz7</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:startEvent id="helm_uninstall_start">
+      <bpmn:outgoing>Flow_0f5dibe</bpmn:outgoing>
+    </bpmn:startEvent>
+    <bpmn:boundaryEvent id="helm_uninstall_Event_0cfcuv3" name="Overall Wait" attachedToRef="Activity_1exvnm9">
+      <bpmn:outgoing>helm_uninstall_Flow_1719q6v</bpmn:outgoing>
+      <bpmn:timerEventDefinition id="TimerEventDefinition_1258pyb">
+        <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT20M</bpmn:timeDuration>
+      </bpmn:timerEventDefinition>
+    </bpmn:boundaryEvent>
+    <bpmn:sequenceFlow id="helm_uninstall_Flow_1f87oz7" sourceRef="helm_uninstall_Activity_0a4jpkd" targetRef="helm_uninstall_Event_0v9a531" />
+    <bpmn:sequenceFlow id="Flow_0f5dibe" sourceRef="helm_uninstall_start" targetRef="Activity_1exvnm9" />
+    <bpmn:sequenceFlow id="helm_uninstall_Flow_1kpnioc" sourceRef="Activity_1exvnm9" targetRef="helm_uninstall_Activity_0a4jpkd" />
+    <bpmn:sequenceFlow id="helm_uninstall_Flow_0qm63h0" sourceRef="helm_uninstall_Activity_09s0jak" targetRef="helm_uninstall_Event_119znxi" />
+    <bpmn:sequenceFlow id="helm_uninstall_Flow_1719q6v" sourceRef="helm_uninstall_Event_0cfcuv3" targetRef="helm_uninstall_Activity_09s0jak" />
+  </bpmn:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="MonitorHelmUnInstallStatus">
+      <bpmndi:BPMNEdge id="Flow_1719q6v_di" bpmnElement="helm_uninstall_Flow_1719q6v">
+        <di:waypoint x="1012" y="372" />
+        <di:waypoint x="1093" y="372" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0qm63h0_di" bpmnElement="helm_uninstall_Flow_0qm63h0">
+        <di:waypoint x="1193" y="372" />
+        <di:waypoint x="1272" y="372" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1kpnioc_di" bpmnElement="helm_uninstall_Flow_1kpnioc">
+        <di:waypoint x="733" y="270" />
+        <di:waypoint x="733" y="150" />
+        <di:waypoint x="1093" y="150" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0f5dibe_di" bpmnElement="Flow_0f5dibe">
+        <di:waypoint x="237" y="380" />
+        <di:waypoint x="319" y="380" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1f87oz7_di" bpmnElement="helm_uninstall_Flow_1f87oz7">
+        <di:waypoint x="1193" y="150" />
+        <di:waypoint x="1272" y="150" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="Event_0v9a531_di" bpmnElement="helm_uninstall_Event_0v9a531">
+        <dc:Bounds x="1272" y="132" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1exvnm9_di" bpmnElement="Activity_1exvnm9" isExpanded="true">
+        <dc:Bounds x="319" y="270" width="675" height="220" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="Flow_0kdhub4_di" bpmnElement="helm_uninstall_Flow_0kdhub4">
+        <di:waypoint x="695" y="356" />
+        <di:waypoint x="779" y="356" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0n6qu57_di" bpmnElement="helm_uninstall_Flow_0n6qu57">
+        <di:waypoint x="829" y="356" />
+        <di:waypoint x="892" y="356" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1g3xchu_di" bpmnElement="helm_uninstall_Flow_1g3xchu">
+        <di:waypoint x="804" y="381" />
+        <di:waypoint x="804" y="428" />
+        <di:waypoint x="756" y="428" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0tqwb9b_di" bpmnElement="helm_uninstall_Flow_0tqwb9b">
+        <di:waypoint x="720" y="428" />
+        <di:waypoint x="656" y="428" />
+        <di:waypoint x="656" y="399" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1kekeh7_di" bpmnElement="helm_uninstall_Flow_1kekeh7">
+        <di:waypoint x="387" y="356" />
+        <di:waypoint x="439" y="356" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_11mzqci_di" bpmnElement="helm_uninstall_Flow_11mzqci">
+        <di:waypoint x="539" y="356" />
+        <di:waypoint x="595" y="356" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="Event_1m6vi78_di" bpmnElement="helm_uninstall_Event_1m6vi78">
+        <dc:Bounds x="351" y="338" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Gateway_0neju2q_di" bpmnElement="helm_uninstall_Gateway_0neju2q" isMarkerVisible="true">
+        <dc:Bounds x="779" y="331" width="50" height="50" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_0lx9pd7_di" bpmnElement="helm_uninstall_Event_0lx9pd7">
+        <dc:Bounds x="720" y="410" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="707" y="453" width="67" height="27" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_1pka4w4_di" bpmnElement="helm_uninstall_Event_1pka4w4">
+        <dc:Bounds x="892" y="338" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0rxj50o_di" bpmnElement="helm_uninstall_Activity_0rxj50o">
+        <dc:Bounds x="595" y="316" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1cc0pq6_di" bpmnElement="helm_uninstall_Activity_1cc0pq6">
+        <dc:Bounds x="439" y="316" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_119znxi_di" bpmnElement="helm_uninstall_Event_119znxi">
+        <dc:Bounds x="1272" y="354" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1265" y="314" width="49" height="27" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_09s0jak_di" bpmnElement="helm_uninstall_Activity_09s0jak">
+        <dc:Bounds x="1093" y="332" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0a4jpkd_di" bpmnElement="helm_uninstall_Activity_0a4jpkd">
+        <dc:Bounds x="1093" y="110" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_1kp76of_di" bpmnElement="helm_uninstall_start">
+        <dc:Bounds x="201" y="362" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_0cfcuv3_di" bpmnElement="helm_uninstall_Event_0cfcuv3">
+        <dc:Bounds x="976" y="354" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="965" y="393" width="60" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn:definitions>
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/resources/TerminateAs.bpmn b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/resources/TerminateAs.bpmn
new file mode 100644 (file)
index 0000000..2cdb78d
--- /dev/null
@@ -0,0 +1,352 @@
+<?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_0hd6h06" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.12.0">
+  <bpmn:process id="TerminateAs" name="TerminateAs" isExecutable="true">
+    <bpmn:startEvent id="StartEvent_1">
+      <bpmn:outgoing>Flow_0phigr7</bpmn:outgoing>
+    </bpmn:startEvent>
+    <bpmn:endEvent id="Event_1xeof55">
+      <bpmn:incoming>Flow_05pzpgq</bpmn:incoming>
+    </bpmn:endEvent>
+    <bpmn:sequenceFlow id="Flow_0phigr7" sourceRef="StartEvent_1" targetRef="Activity_15qf8s9" />
+    <bpmn:serviceTask id="Activity_15qf8s9" name="Set Job Status to STARTED" camunda:asyncBefore="true" camunda:expression="${TerminateAsTask.setJobStatusToStarted(execution)}">
+      <bpmn:incoming>Flow_0phigr7</bpmn:incoming>
+      <bpmn:outgoing>Flow_06wp5ro</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_06wp5ro" sourceRef="Activity_15qf8s9" targetRef="Activity_1a903iq" />
+    <bpmn:subProcess id="Activity_0zqv5cb" name="Java Exception Handling" triggeredByEvent="true">
+      <bpmn:serviceTask id="Activity_18d5zjd" name="Update AsLcmOpOcc operation status to FAILED" camunda:asyncBefore="true" camunda:expression="${TerminateAsTask.updateAsLcmOpOccStatusToFailed(execution)}">
+        <bpmn:incoming>Flow_1xjr8hb</bpmn:incoming>
+        <bpmn:outgoing>Flow_1ggg282</bpmn:outgoing>
+      </bpmn:serviceTask>
+      <bpmn:serviceTask id="Activity_0usyzj5" name="Set Job Status to ERROR" camunda:asyncBefore="true" camunda:expression="${TerminateAsTask.setJobStatusToError(execution)}">
+        <bpmn:incoming>Flow_1ah8wba</bpmn:incoming>
+        <bpmn:outgoing>Flow_117o05v</bpmn:outgoing>
+      </bpmn:serviceTask>
+      <bpmn:endEvent id="Event_1pgel48">
+        <bpmn:incoming>Flow_117o05v</bpmn:incoming>
+      </bpmn:endEvent>
+      <bpmn:startEvent id="Event_0sx56px" name="error">
+        <bpmn:outgoing>Flow_1xjr8hb</bpmn:outgoing>
+        <bpmn:errorEventDefinition id="ErrorEventDefinition_0gxzhu7" errorRef="Error_0t56zia" camunda:errorCodeVariable="BPMN_javaExpCode" camunda:errorMessageVariable="BPMN_javaExpMsg" />
+      </bpmn:startEvent>
+      <bpmn:sequenceFlow id="Flow_1ggg282" sourceRef="Activity_18d5zjd" targetRef="Activity_1uoyj49" />
+      <bpmn:sequenceFlow id="Flow_1xjr8hb" sourceRef="Event_0sx56px" targetRef="Activity_18d5zjd" />
+      <bpmn:sequenceFlow id="Flow_117o05v" sourceRef="Activity_0usyzj5" targetRef="Event_1pgel48" />
+      <bpmn:serviceTask id="Activity_1uoyj49" name="Set AsInstance status to Failed" camunda:expression="${TerminateAsTask.setAsInstanceStatusToFailed(execution)}">
+        <bpmn:incoming>Flow_1ggg282</bpmn:incoming>
+        <bpmn:outgoing>Flow_1ah8wba</bpmn:outgoing>
+      </bpmn:serviceTask>
+      <bpmn:sequenceFlow id="Flow_1ah8wba" sourceRef="Activity_1uoyj49" targetRef="Activity_0usyzj5" />
+    </bpmn:subProcess>
+    <bpmn:subProcess id="Activity_1eo7tbl" name="Error Handling" triggeredByEvent="true">
+      <bpmn:serviceTask id="Activity_10eh71a" name="Update AsLcmOpOcc operation status to FAILED" camunda:asyncBefore="true" camunda:expression="${TerminateAsTask.updateAsLcmOpOccStatusToFailed(execution)}">
+        <bpmn:incoming>Flow_0r7a1v7</bpmn:incoming>
+        <bpmn:outgoing>Flow_0762ta8</bpmn:outgoing>
+      </bpmn:serviceTask>
+      <bpmn:serviceTask id="Activity_0y3x784" name="Set Job Status to ERROR" camunda:asyncBefore="true" camunda:expression="${TerminateAsTask.setJobStatusToError(execution)}">
+        <bpmn:incoming>Flow_1qhfzp9</bpmn:incoming>
+        <bpmn:outgoing>Flow_014quwi</bpmn:outgoing>
+      </bpmn:serviceTask>
+      <bpmn:endEvent id="Event_0gmyixw" name="end">
+        <bpmn:incoming>Flow_014quwi</bpmn:incoming>
+      </bpmn:endEvent>
+      <bpmn:startEvent id="Event_01ll1gt" name="error">
+        <bpmn:outgoing>Flow_0r7a1v7</bpmn:outgoing>
+        <bpmn:errorEventDefinition id="ErrorEventDefinition_197igu6" />
+      </bpmn:startEvent>
+      <bpmn:sequenceFlow id="Flow_0762ta8" sourceRef="Activity_10eh71a" targetRef="Activity_1xuk084" />
+      <bpmn:sequenceFlow id="Flow_0r7a1v7" sourceRef="Event_01ll1gt" targetRef="Activity_10eh71a" />
+      <bpmn:sequenceFlow id="Flow_014quwi" sourceRef="Activity_0y3x784" targetRef="Event_0gmyixw" />
+      <bpmn:sequenceFlow id="Flow_1qhfzp9" sourceRef="Activity_1xuk084" targetRef="Activity_0y3x784" />
+      <bpmn:serviceTask id="Activity_1xuk084" name="Set AsInstance status to Failed" camunda:expression="${TerminateAsTask.setAsInstanceStatusToFailed(execution)}">
+        <bpmn:incoming>Flow_0762ta8</bpmn:incoming>
+        <bpmn:outgoing>Flow_1qhfzp9</bpmn:outgoing>
+      </bpmn:serviceTask>
+    </bpmn:subProcess>
+    <bpmn:serviceTask id="Activity_0hvh6ls" name="Update AsLcmOpOcc operation status to COMPLETED" camunda:expression="${TerminateAsTask.updateAsLcmOpOccStatusToCompleted(execution)}">
+      <bpmn:incoming>Flow_1rn2equ</bpmn:incoming>
+      <bpmn:outgoing>Flow_13oh37n</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_13oh37n" sourceRef="Activity_0hvh6ls" targetRef="Activity_0lei5vt" />
+    <bpmn:serviceTask id="Activity_1a903iq" name="Update AS Instance status to TERMINATING" camunda:expression="${TerminateAsTask.updateAsInstanceStatusToTerminating(execution)}">
+      <bpmn:incoming>Flow_06wp5ro</bpmn:incoming>
+      <bpmn:outgoing>Flow_1b3sgnv</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_1b3sgnv" sourceRef="Activity_1a903iq" targetRef="Check_if_Kube_Config_file_available_on_filesystem" />
+    <bpmn:serviceTask id="Check_if_Kube_Config_file_available_on_filesystem" name="Check if Kube Config file available on filesystem" camunda:expression="${TerminateAsTask.checkifKubConfigFileAvailable(execution)}">
+      <bpmn:incoming>Flow_1b3sgnv</bpmn:incoming>
+      <bpmn:outgoing>Flow_08hpasa</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_08hpasa" sourceRef="Check_if_Kube_Config_file_available_on_filesystem" targetRef="Prepare_Terminate_Deployment_Item_requests" />
+    <bpmn:serviceTask id="Prepare_Terminate_Deployment_Item_requests" name="Prepare Terminate Deployment Item requests" camunda:expression="${TerminateAsTask.prepareTerminateDeploymentItemRequests(execution)}">
+      <bpmn:incoming>Flow_08hpasa</bpmn:incoming>
+      <bpmn:outgoing>Flow_13hlp85</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:serviceTask id="Check_if_Deployment_Items_Termination_was_Successful" name="Check if Deployment Items Termination was Successful" camunda:expression="${TerminateAsTask.checkIfDeploymentItemsTerminationWasSuccessful(execution)}">
+      <bpmn:incoming>Flow_03u3m4k</bpmn:incoming>
+      <bpmn:outgoing>Flow_031y9cv</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:callActivity id="Terminate_each_Deployment_Item" name="Terminate each Deployment Item" calledElement="TerminateDeploymentItem">
+      <bpmn:extensionElements>
+        <camunda:in source="request" target="request" />
+        <camunda:in source="jobId" target="jobId" />
+        <camunda:in source="AsInstanceId" target="AsInstanceId" />
+      </bpmn:extensionElements>
+      <bpmn:incoming>Flow_13hlp85</bpmn:incoming>
+      <bpmn:outgoing>Flow_03u3m4k</bpmn:outgoing>
+      <bpmn:multiInstanceLoopCharacteristics isSequential="true" camunda:asyncAfter="true" camunda:collection="${deploymentItemTerminateRequests}" camunda:elementVariable="request" />
+    </bpmn:callActivity>
+    <bpmn:exclusiveGateway id="Gateway_06foddt" name="is Successful?">
+      <bpmn:incoming>Flow_031y9cv</bpmn:incoming>
+      <bpmn:outgoing>Flow_1va2hjh</bpmn:outgoing>
+      <bpmn:outgoing>Flow_1daazvp</bpmn:outgoing>
+    </bpmn:exclusiveGateway>
+    <bpmn:endEvent id="Event_0iz85ln">
+      <bpmn:incoming>Flow_1va2hjh</bpmn:incoming>
+      <bpmn:incoming>Flow_0i1vt5a</bpmn:incoming>
+      <bpmn:errorEventDefinition id="ErrorEventDefinition_0uqpvyg" errorRef="Error_0t56zia" />
+    </bpmn:endEvent>
+    <bpmn:sequenceFlow id="Flow_031y9cv" sourceRef="Check_if_Deployment_Items_Termination_was_Successful" targetRef="Gateway_06foddt" />
+    <bpmn:sequenceFlow id="Flow_03u3m4k" sourceRef="Terminate_each_Deployment_Item" targetRef="Check_if_Deployment_Items_Termination_was_Successful" />
+    <bpmn:sequenceFlow id="Flow_1va2hjh" name="No" sourceRef="Gateway_06foddt" targetRef="Event_0iz85ln">
+      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{not isAsTerminationSuccessful}</bpmn:conditionExpression>
+    </bpmn:sequenceFlow>
+    <bpmn:sequenceFlow id="Flow_13hlp85" sourceRef="Prepare_Terminate_Deployment_Item_requests" targetRef="Terminate_each_Deployment_Item" />
+    <bpmn:sequenceFlow id="Flow_1daazvp" name="Yes" sourceRef="Gateway_06foddt" targetRef="Activity_176on9n">
+      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{isAsTerminationSuccessful}</bpmn:conditionExpression>
+    </bpmn:sequenceFlow>
+    <bpmn:sequenceFlow id="Flow_0vuf6k8" sourceRef="Activity_176on9n" targetRef="Activity_1yslkij" />
+    <bpmn:serviceTask id="Activity_176on9n" name="Update Generic VNF status to &#39;Deactivated&#39;" camunda:expression="${TerminateAsTask.updateGenericVnfStatustoDeActivated(execution)}">
+      <bpmn:incoming>Flow_1daazvp</bpmn:incoming>
+      <bpmn:outgoing>Flow_0vuf6k8</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:serviceTask id="Activity_0lei5vt" name="Set Job Status to FINISHED" camunda:expression="${TerminateAsTask.setJobStatusToFinished(execution)}">
+      <bpmn:incoming>Flow_13oh37n</bpmn:incoming>
+      <bpmn:outgoing>Flow_05pzpgq</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_05pzpgq" sourceRef="Activity_0lei5vt" targetRef="Event_1xeof55" />
+    <bpmn:serviceTask id="Activity_1yslkij" name="Update AS Instance status to NOT_INSTANTIATED" camunda:expression="${TerminateAsTask.updateAsInstanceStatusToNotInstantiated(execution)}">
+      <bpmn:incoming>Flow_0vuf6k8</bpmn:incoming>
+      <bpmn:outgoing>Flow_1rn2equ</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_1rn2equ" sourceRef="Activity_1yslkij" targetRef="Activity_0hvh6ls" />
+    <bpmn:serviceTask id="Log_TimeOut" name="Log TimeOut" camunda:expression="${TerminateAsTask.logTimeOut(execution)}">
+      <bpmn:incoming>Flow_0do9jeh</bpmn:incoming>
+      <bpmn:outgoing>Flow_0i1vt5a</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_0i1vt5a" sourceRef="Log_TimeOut" targetRef="Event_0iz85ln" />
+    <bpmn:boundaryEvent id="Terminate_deployment_overall_" name="Overall Wait" attachedToRef="Terminate_each_Deployment_Item">
+      <bpmn:outgoing>Flow_0do9jeh</bpmn:outgoing>
+      <bpmn:timerEventDefinition id="TimerEventDefinition_11u0ekp">
+        <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT3H</bpmn:timeDuration>
+      </bpmn:timerEventDefinition>
+    </bpmn:boundaryEvent>
+    <bpmn:sequenceFlow id="Flow_0do9jeh" sourceRef="Terminate_deployment_overall_" targetRef="Log_TimeOut" />
+  </bpmn:process>
+  <bpmn:error id="Error_1m0gknf" name="NsWorkflowProcessingException" errorCode="INSTANTIATE_NS_WORKFLOW_PROCESSING_EXCEPTION" />
+  <bpmn:error id="Error_0t56zia" name="AsWorkflowProcessingException" errorCode="TERMINATE_AS_WORKFLOW_PROCESSING_EXCEPTION" />
+  <bpmn:error id="Error_1iguqth" name="Error_0p8dv5a" />
+  <bpmn:error id="Error_1bbjzv9" name="Error_1lepva9" />
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="TerminateAs">
+      <bpmndi:BPMNEdge id="Flow_0do9jeh_di" bpmnElement="Flow_0do9jeh">
+        <di:waypoint x="940" y="152" />
+        <di:waypoint x="940" y="260" />
+        <di:waypoint x="1000" y="260" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0i1vt5a_di" bpmnElement="Flow_0i1vt5a">
+        <di:waypoint x="1100" y="260" />
+        <di:waypoint x="1152" y="260" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1rn2equ_di" bpmnElement="Flow_1rn2equ">
+        <di:waypoint x="1505" y="94" />
+        <di:waypoint x="1555" y="94" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_05pzpgq_di" bpmnElement="Flow_05pzpgq">
+        <di:waypoint x="1815" y="94" />
+        <di:waypoint x="1877" y="94" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0vuf6k8_di" bpmnElement="Flow_0vuf6k8">
+        <di:waypoint x="1358" y="94" />
+        <di:waypoint x="1405" y="94" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1daazvp_di" bpmnElement="Flow_1daazvp">
+        <di:waypoint x="1195" y="94" />
+        <di:waypoint x="1258" y="94" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1210" y="76" width="19" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_13hlp85_di" bpmnElement="Flow_13hlp85">
+        <di:waypoint x="793" y="97" />
+        <di:waypoint x="860" y="97" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1va2hjh_di" bpmnElement="Flow_1va2hjh">
+        <di:waypoint x="1170" y="119" />
+        <di:waypoint x="1170" y="242" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1178" y="178" width="15" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_03u3m4k_di" bpmnElement="Flow_03u3m4k">
+        <di:waypoint x="960" y="94" />
+        <di:waypoint x="1000" y="94" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_031y9cv_di" bpmnElement="Flow_031y9cv">
+        <di:waypoint x="1100" y="94" />
+        <di:waypoint x="1145" y="94" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_08hpasa_di" bpmnElement="Flow_08hpasa">
+        <di:waypoint x="643" y="97" />
+        <di:waypoint x="693" y="97" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1b3sgnv_di" bpmnElement="Flow_1b3sgnv">
+        <di:waypoint x="503" y="97" />
+        <di:waypoint x="543" y="97" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_13oh37n_di" bpmnElement="Flow_13oh37n">
+        <di:waypoint x="1655" y="94" />
+        <di:waypoint x="1715" y="94" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_06wp5ro_di" bpmnElement="Flow_06wp5ro">
+        <di:waypoint x="351" y="97" />
+        <di:waypoint x="403" y="97" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0phigr7_di" bpmnElement="Flow_0phigr7">
+        <di:waypoint x="198" y="97" />
+        <di:waypoint x="251" y="97" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+        <dc:Bounds x="162" y="79" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_1xeof55_di" bpmnElement="Event_1xeof55">
+        <dc:Bounds x="1877" y="76" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_15qf8s9_di" bpmnElement="Activity_15qf8s9">
+        <dc:Bounds x="251" y="57" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0zqv5cb_di" bpmnElement="Activity_0zqv5cb" isExpanded="true">
+        <dc:Bounds x="488" y="520" width="700" height="130" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="Flow_1ah8wba_di" bpmnElement="Flow_1ah8wba">
+        <di:waypoint x="880" y="583" />
+        <di:waypoint x="950" y="583" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_117o05v_di" bpmnElement="Flow_117o05v">
+        <di:waypoint x="1050" y="583" />
+        <di:waypoint x="1112" y="583" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1xjr8hb_di" bpmnElement="Flow_1xjr8hb">
+        <di:waypoint x="546" y="583" />
+        <di:waypoint x="608" y="583" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1ggg282_di" bpmnElement="Flow_1ggg282">
+        <di:waypoint x="708" y="583" />
+        <di:waypoint x="780" y="583" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="Activity_18d5zjd_di" bpmnElement="Activity_18d5zjd">
+        <dc:Bounds x="608" y="543" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0usyzj5_di" bpmnElement="Activity_0usyzj5">
+        <dc:Bounds x="950" y="543" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_1pgel48_di" bpmnElement="Event_1pgel48">
+        <dc:Bounds x="1112" y="565" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_0sx56px_di" bpmnElement="Event_0sx56px">
+        <dc:Bounds x="510" y="565" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="517" y="608" width="24" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1uoyj49_di" bpmnElement="Activity_1uoyj49">
+        <dc:Bounds x="780" y="543" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1eo7tbl_di" bpmnElement="Activity_1eo7tbl" isExpanded="true">
+        <dc:Bounds x="488" y="350" width="700" height="130" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="Flow_1qhfzp9_di" bpmnElement="Flow_1qhfzp9">
+        <di:waypoint x="880" y="413" />
+        <di:waypoint x="950" y="413" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_014quwi_di" bpmnElement="Flow_014quwi">
+        <di:waypoint x="1050" y="413" />
+        <di:waypoint x="1112" y="413" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0r7a1v7_di" bpmnElement="Flow_0r7a1v7">
+        <di:waypoint x="546" y="413" />
+        <di:waypoint x="608" y="413" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0762ta8_di" bpmnElement="Flow_0762ta8">
+        <di:waypoint x="708" y="413" />
+        <di:waypoint x="780" y="413" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="Activity_10eh71a_di" bpmnElement="Activity_10eh71a">
+        <dc:Bounds x="608" y="373" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0y3x784_di" bpmnElement="Activity_0y3x784">
+        <dc:Bounds x="950" y="373" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_0gmyixw_di" bpmnElement="Event_0gmyixw">
+        <dc:Bounds x="1112" y="395" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1122" y="437" width="19" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_01ll1gt_di" bpmnElement="Event_01ll1gt">
+        <dc:Bounds x="510" y="395" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="516" y="438" width="24" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0521h5r_di" bpmnElement="Activity_1xuk084">
+        <dc:Bounds x="780" y="373" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0hvh6ls_di" bpmnElement="Activity_0hvh6ls">
+        <dc:Bounds x="1555" y="54" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1a903iq_di" bpmnElement="Activity_1a903iq">
+        <dc:Bounds x="403" y="57" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Check_if_Kube_Config_file_available_on_filesystem_di" bpmnElement="Check_if_Kube_Config_file_available_on_filesystem">
+        <dc:Bounds x="543" y="57" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Prepare_Terminate_Deployment_Item_requests_di" bpmnElement="Prepare_Terminate_Deployment_Item_requests">
+        <dc:Bounds x="693" y="57" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Check_if_Deployment_Items_Termination_was_Successful_di" bpmnElement="Check_if_Deployment_Items_Termination_was_Successful">
+        <dc:Bounds x="1000" y="54" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Terminate_each_Deployment_Item_di" bpmnElement="Terminate_each_Deployment_Item">
+        <dc:Bounds x="860" y="54" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Gateway_06foddt_di" bpmnElement="Gateway_06foddt" isMarkerVisible="true">
+        <dc:Bounds x="1145" y="69" width="50" height="50" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1140" y="39" width="71" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_0iz85ln_di" bpmnElement="Event_0iz85ln">
+        <dc:Bounds x="1152" y="242" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1bzk21b_di" bpmnElement="Activity_176on9n">
+        <dc:Bounds x="1258" y="54" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0lei5vt_di" bpmnElement="Activity_0lei5vt">
+        <dc:Bounds x="1715" y="54" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1yslkij_di" bpmnElement="Activity_1yslkij">
+        <dc:Bounds x="1405" y="54" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Log_TimeOut_di" bpmnElement="Log_TimeOut">
+        <dc:Bounds x="1000" y="220" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_056xxf3_di" bpmnElement="Terminate_deployment_overall_">
+        <dc:Bounds x="922" y="116" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="950" y="163" width="60" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn:definitions>
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/resources/TerminateDeploymentItem.bpmn b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/resources/TerminateDeploymentItem.bpmn
new file mode 100644 (file)
index 0000000..d5b2073
--- /dev/null
@@ -0,0 +1,199 @@
+<?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:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1va0vwc" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.12.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">
+  <bpmn:process id="TerminateDeploymentItem" isExecutable="true">
+    <bpmn:startEvent id="Terminate_deployment_start_event">
+      <bpmn:outgoing>Flow_11nr4yl</bpmn:outgoing>
+    </bpmn:startEvent>
+    <bpmn:sequenceFlow id="Flow_11nr4yl" sourceRef="Terminate_deployment_start_event" targetRef="Activity_08pudch" />
+    <bpmn:serviceTask id="Activity_0sj1npl" name="Uninstantiate Helm Chart Using uninstall cmd" camunda:expression="${TerminateDeploymentItemTask.unInstantiateHelmChart(execution)}">
+      <bpmn:incoming>Flow_1ey2cql</bpmn:incoming>
+      <bpmn:outgoing>Flow_0hqyoqt</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_0ks1v6p" sourceRef="Activity_08pudch" targetRef="Activity_1d6qam7" />
+    <bpmn:serviceTask id="Activity_08pudch" name="Check If Deployment Item exists in DB" camunda:expression="${TerminateDeploymentItemTask.checkIfDeploymentItemExistsInDb(execution)}">
+      <bpmn:incoming>Flow_11nr4yl</bpmn:incoming>
+      <bpmn:outgoing>Flow_0ks1v6p</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:endEvent id="Event_11evvnx">
+      <bpmn:incoming>Flow_0gcia1l</bpmn:incoming>
+    </bpmn:endEvent>
+    <bpmn:serviceTask id="Activity_0zhk457" name="Update Deployment Item Status to Not Instantiated" camunda:expression="${TerminateDeploymentItemTask.updateDeploymentItemStatusToNotInstantiated(execution)}">
+      <bpmn:incoming>Flow_044y6ke</bpmn:incoming>
+      <bpmn:outgoing>Flow_0gcia1l</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_0gcia1l" sourceRef="Activity_0zhk457" targetRef="Event_11evvnx" />
+    <bpmn:callActivity id="Activity_1643ozm" name="Monitor Helm UnInstall Status" calledElement="MonitorHelmUnInstallStatus">
+      <bpmn:extensionElements>
+        <camunda:in source="kind" target="kind" />
+        <camunda:in source="jobId" target="jobId" />
+        <camunda:in source="asDeploymentItemInstId" target="asDeploymentItemInstId" />
+        <camunda:in source="kubeKindsResult" target="kubeKindsResult" />
+        <camunda:out source="kubeKindsResult" target="kubeKindsResult" />
+        <camunda:in source="releaseName" target="releaseName" />
+        <camunda:in source="kubeConfigFilePath" target="kubeConfigFilePath" />
+      </bpmn:extensionElements>
+      <bpmn:incoming>Flow_0hqyoqt</bpmn:incoming>
+      <bpmn:outgoing>Flow_0tc7pv4</bpmn:outgoing>
+      <bpmn:multiInstanceLoopCharacteristics isSequential="true" camunda:asyncAfter="true" camunda:collection="${kubeKinds}" camunda:elementVariable="kind" />
+    </bpmn:callActivity>
+    <bpmn:serviceTask id="Activity_0mm2cjf" name="Log TimeOut" camunda:expression="${InstantiateDeploymentItemTask.logTimeOut(execution)}">
+      <bpmn:incoming>Flow_151tn6a</bpmn:incoming>
+      <bpmn:outgoing>Flow_0mnd6tu</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:serviceTask id="Activity_1sj22rm" name="Check if Helm Uninstall was Successful" camunda:expression="${TerminateDeploymentItemTask.checkIfHelmUnInstallWasSuccessful(execution)}">
+      <bpmn:incoming>Flow_0tc7pv4</bpmn:incoming>
+      <bpmn:outgoing>Flow_0k6smfs</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:endEvent id="Event_0ye4mrr">
+      <bpmn:incoming>Flow_0mnd6tu</bpmn:incoming>
+      <bpmn:incoming>Flow_1v7gngy</bpmn:incoming>
+      <bpmn:errorEventDefinition id="ErrorEventDefinition_07j9982" errorRef="Error_04z28em" />
+    </bpmn:endEvent>
+    <bpmn:exclusiveGateway id="Gateway_08p31bc">
+      <bpmn:incoming>Flow_0k6smfs</bpmn:incoming>
+      <bpmn:outgoing>Flow_1v7gngy</bpmn:outgoing>
+      <bpmn:outgoing>Flow_0pdqj64</bpmn:outgoing>
+    </bpmn:exclusiveGateway>
+    <bpmn:serviceTask id="Activity_093v0t4" name="Delete K8 resources related to vfmodule" camunda:expression="${TerminateDeploymentItemTask.deleteK8ResourcesinAAI(execution)}">
+      <bpmn:incoming>Flow_0pdqj64</bpmn:incoming>
+      <bpmn:outgoing>Flow_0rpkgfk</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:serviceTask id="Activity_1jdaz83" name="Delete VF Module" camunda:expression="${TerminateDeploymentItemTask.deleteVFModuleinAai(execution)}">
+      <bpmn:incoming>Flow_0rpkgfk</bpmn:incoming>
+      <bpmn:outgoing>Flow_044y6ke</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:boundaryEvent id="Event_04fi7zc" name="Overall Wait" attachedToRef="Activity_1643ozm">
+      <bpmn:outgoing>Flow_151tn6a</bpmn:outgoing>
+      <bpmn:timerEventDefinition id="TimerEventDefinition_0yun371">
+        <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT1H</bpmn:timeDuration>
+      </bpmn:timerEventDefinition>
+    </bpmn:boundaryEvent>
+    <bpmn:sequenceFlow id="Flow_0tc7pv4" sourceRef="Activity_1643ozm" targetRef="Activity_1sj22rm" />
+    <bpmn:sequenceFlow id="Flow_0mnd6tu" sourceRef="Activity_0mm2cjf" targetRef="Event_0ye4mrr" />
+    <bpmn:sequenceFlow id="Flow_0k6smfs" sourceRef="Activity_1sj22rm" targetRef="Gateway_08p31bc" />
+    <bpmn:sequenceFlow id="Flow_1v7gngy" name="No" sourceRef="Gateway_08p31bc" targetRef="Event_0ye4mrr">
+      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{not isDeleted}</bpmn:conditionExpression>
+    </bpmn:sequenceFlow>
+    <bpmn:sequenceFlow id="Flow_0pdqj64" name="Yes" sourceRef="Gateway_08p31bc" targetRef="Activity_093v0t4">
+      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{isDeleted}</bpmn:conditionExpression>
+    </bpmn:sequenceFlow>
+    <bpmn:sequenceFlow id="Flow_0rpkgfk" sourceRef="Activity_093v0t4" targetRef="Activity_1jdaz83" />
+    <bpmn:sequenceFlow id="Flow_151tn6a" sourceRef="Event_04fi7zc" targetRef="Activity_0mm2cjf" />
+    <bpmn:sequenceFlow id="Flow_0hqyoqt" sourceRef="Activity_0sj1npl" targetRef="Activity_1643ozm" />
+    <bpmn:sequenceFlow id="Flow_044y6ke" sourceRef="Activity_1jdaz83" targetRef="Activity_0zhk457" />
+    <bpmn:serviceTask id="Activity_1d6qam7" name="Get kube kinds" camunda:expression="${TerminateDeploymentItemTask.getKubeKindsUsingManifestCommand(execution)}">
+      <bpmn:incoming>Flow_0ks1v6p</bpmn:incoming>
+      <bpmn:outgoing>Flow_1ey2cql</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="Flow_1ey2cql" sourceRef="Activity_1d6qam7" targetRef="Activity_0sj1npl" />
+  </bpmn:process>
+  <bpmn:error id="Error_04z28em" name="AsWorkflowProcessingException" errorCode="INSTANTIATE_AS_WORKFLOW_PROCESSING_EXCEPTION" />
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="TerminateDeploymentItem">
+      <bpmndi:BPMNEdge id="Flow_044y6ke_di" bpmnElement="Flow_044y6ke">
+        <di:waypoint x="1510" y="120" />
+        <di:waypoint x="1590" y="120" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0hqyoqt_di" bpmnElement="Flow_0hqyoqt">
+        <di:waypoint x="670" y="120" />
+        <di:waypoint x="740" y="120" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_151tn6a_di" bpmnElement="Flow_151tn6a">
+        <di:waypoint x="820" y="178" />
+        <di:waypoint x="820" y="300" />
+        <di:waypoint x="920" y="300" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0rpkgfk_di" bpmnElement="Flow_0rpkgfk">
+        <di:waypoint x="1320" y="120" />
+        <di:waypoint x="1410" y="120" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0pdqj64_di" bpmnElement="Flow_0pdqj64">
+        <di:waypoint x="1155" y="120" />
+        <di:waypoint x="1220" y="120" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1178" y="102" width="19" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1v7gngy_di" bpmnElement="Flow_1v7gngy">
+        <di:waypoint x="1130" y="145" />
+        <di:waypoint x="1130" y="282" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1138" y="211" width="15" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0k6smfs_di" bpmnElement="Flow_0k6smfs">
+        <di:waypoint x="1020" y="120" />
+        <di:waypoint x="1105" y="120" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0mnd6tu_di" bpmnElement="Flow_0mnd6tu">
+        <di:waypoint x="1020" y="300" />
+        <di:waypoint x="1112" y="300" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0tc7pv4_di" bpmnElement="Flow_0tc7pv4">
+        <di:waypoint x="840" y="120" />
+        <di:waypoint x="920" y="120" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0gcia1l_di" bpmnElement="Flow_0gcia1l">
+        <di:waypoint x="1690" y="120" />
+        <di:waypoint x="1762" y="120" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0ks1v6p_di" bpmnElement="Flow_0ks1v6p">
+        <di:waypoint x="340" y="120" />
+        <di:waypoint x="400" y="120" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_11nr4yl_di" bpmnElement="Flow_11nr4yl">
+        <di:waypoint x="188" y="120" />
+        <di:waypoint x="240" y="120" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1ey2cql_di" bpmnElement="Flow_1ey2cql">
+        <di:waypoint x="500" y="120" />
+        <di:waypoint x="570" y="120" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="Event_0fwtu82_di" bpmnElement="Terminate_deployment_start_event">
+        <dc:Bounds x="152" y="102" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0ij2kxo_di" bpmnElement="Activity_08pudch">
+        <dc:Bounds x="240" y="80" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0sj1npl_di" bpmnElement="Activity_0sj1npl">
+        <dc:Bounds x="570" y="80" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1d6qam7_di" bpmnElement="Activity_1d6qam7">
+        <dc:Bounds x="400" y="80" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_11evvnx_di" bpmnElement="Event_11evvnx">
+        <dc:Bounds x="1762" y="102" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0zhk457_di" bpmnElement="Activity_0zhk457">
+        <dc:Bounds x="1590" y="80" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1643ozm_di" bpmnElement="Activity_1643ozm">
+        <dc:Bounds x="740" y="80" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0mm2cjf_di" bpmnElement="Activity_0mm2cjf">
+        <dc:Bounds x="920" y="260" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1sj22rm_di" bpmnElement="Activity_1sj22rm">
+        <dc:Bounds x="920" y="80" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_0ye4mrr_di" bpmnElement="Event_0ye4mrr">
+        <dc:Bounds x="1112" y="282" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Gateway_08p31bc_di" bpmnElement="Gateway_08p31bc" isMarkerVisible="true">
+        <dc:Bounds x="1105" y="95" width="50" height="50" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_093v0t4_di" bpmnElement="Activity_093v0t4">
+        <dc:Bounds x="1220" y="80" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1jdaz83_di" bpmnElement="Activity_1jdaz83">
+        <dc:Bounds x="1410" y="80" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_04fi7zc_di" bpmnElement="Event_04fi7zc">
+        <dc:Bounds x="802" y="142" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="750" y="182" width="60" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn:definitions>
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/TerminateAsTaskTest.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/test/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/TerminateAsTaskTest.java
new file mode 100644 (file)
index 0000000..832d675
--- /dev/null
@@ -0,0 +1,267 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.tasks;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+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.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.onap.aaiclient.client.aai.AAIVersion.V19;
+import static org.springframework.http.HttpHeaders.CONTENT_TYPE;
+import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
+
+import com.google.gson.Gson;
+import io.kubernetes.client.openapi.models.V1DaemonSetList;
+import io.kubernetes.client.openapi.models.V1DeploymentList;
+import io.kubernetes.client.openapi.models.V1JobList;
+import io.kubernetes.client.openapi.models.V1PodList;
+import io.kubernetes.client.openapi.models.V1ReplicaSetList;
+import io.kubernetes.client.openapi.models.V1ServiceList;
+import io.kubernetes.client.openapi.models.V1StatefulSetList;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import org.camunda.bpm.engine.history.HistoricProcessInstance;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.aai.domain.yang.GenericVnf;
+import org.onap.so.beans.nsmf.OrchestrationStatusEnum;
+import org.onap.so.cnfm.lcm.bpmn.flows.BaseTest;
+import org.onap.so.cnfm.lcm.bpmn.flows.GsonProvider;
+import org.onap.so.cnfm.lcm.bpmn.flows.service.JobExecutorService;
+import org.onap.so.cnfm.lcm.database.beans.AsDeploymentItem;
+import org.onap.so.cnfm.lcm.database.beans.AsInst;
+import org.onap.so.cnfm.lcm.database.beans.AsLcmOpOcc;
+import org.onap.so.cnfm.lcm.database.beans.Job;
+import org.onap.so.cnfm.lcm.database.beans.OperationStateEnum;
+import org.onap.so.cnfm.lcm.database.beans.State;
+import org.onap.so.cnfm.lcm.model.TerminateAsRequest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class TerminateAsTaskTest extends BaseTest {
+
+    private static final String AS_INST_ID = UUID.randomUUID().toString();
+    private static final String AS_DEPLOYMENT_ITEM_ONE_INST_ID = UUID.randomUUID().toString();
+    private static final String AS_DEPLOYMENT_ITEM_TWO_INST_ID = UUID.randomUUID().toString();
+
+    @Value("${cnfm.kube-configs-dir}")
+    private String kubeConfigsDir;
+
+    @Autowired
+    private JobExecutorService objUnderTest;
+
+    @Autowired
+    private MockedHelmClient mockedHelmClient;
+
+    @Autowired
+    private MockedKubernetesClientProvider kubernetesClientProvider;
+
+    @Autowired
+    private GsonProvider gsonProvider;
+
+    private Gson gson;
+
+    @Before
+    public void before() {
+
+        wireMockServer.resetAll();
+        try {
+            deleteFoldersAndFiles(Paths.get(kubeConfigsDir));
+            Files.createDirectory(Paths.get(kubeConfigsDir));
+        } catch (final IOException ioException) {
+            throw new RuntimeException(
+                    "Failed to create/Delete Directory in TerminateAsTaskTest due to: " + ioException.getMessage());
+        }
+        kubernetesClientProvider.setWireMockServer(wireMockServer);
+
+        gson = gsonProvider.getGson();
+    }
+
+    @After
+    public void after() {
+        wireMockServer.resetAll();
+    }
+
+    @Test
+    public void testTerminateAsTask_SuccessfulCase() throws InterruptedException, IOException {
+
+        mockKubernetesClientEndpoint();
+        mockAAIEndPoints();
+        addDummyAsToDatabase(AS_INST_ID);
+
+        final String asLcmOpOccId = objUnderTest.runTerminateAsJob(AS_INST_ID, new TerminateAsRequest());
+
+        final Optional<Job> optional = getJobByResourceId(AS_INST_ID);
+        assertTrue(optional.isPresent());
+        final Job job = optional.get();
+        assertTrue(waitForProcessInstanceToFinish(job.getProcessInstanceId()));
+
+        final HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance(job.getProcessInstanceId());
+        assertNotNull(historicProcessInstance);
+        assertEquals(HistoricProcessInstance.STATE_COMPLETED, historicProcessInstance.getState());
+
+        final Optional<AsInst> optionalAsInst = databaseServiceProvider.getAsInst(AS_INST_ID);
+        assertTrue(optionalAsInst.isPresent());
+        final AsInst updatedAsInst = optionalAsInst.get();
+        assertEquals(State.NOT_INSTANTIATED, updatedAsInst.getStatus());
+
+        final Optional<AsLcmOpOcc> optionalAsLcmOpOcc = databaseServiceProvider.getAsLcmOpOcc(asLcmOpOccId);
+        assertTrue(optionalAsLcmOpOcc.isPresent());
+        final AsLcmOpOcc asLcmOpOcc = optionalAsLcmOpOcc.get();
+        assertEquals(OperationStateEnum.COMPLETED, asLcmOpOcc.getOperationState());
+
+        final Map<String, Integer> counter = mockedHelmClient.getUnInstallCounter();
+        assertEquals(2, counter.size());
+    }
+
+    private void addDummyAsToDatabase(final String asInstanceId) throws IOException {
+        final String asInstName = "TerminateCnfService-" + System.currentTimeMillis();
+        final AsInst asInst = new AsInst().asInstId(asInstanceId).name(asInstName).asdId(asInstanceId)
+                .asdInvariantId(asInstanceId).status(State.INSTANTIATED).statusUpdatedTime(LocalDateTime.now())
+                .asApplicationName("asApplicationName").asApplicationVersion("asApplicationVersion")
+                .asProvider("asProvider").serviceInstanceId(SERVICE_INSTANCE_ID)
+                .serviceInstanceName(SERVICE_INSTANCE_NAME).cloudOwner("cloudOwner").cloudRegion("cloudRegion")
+                .tenantId("tenantId");
+
+        final String helmFile1 = "Artifacts/Deployment/HELM/sampleapp-db-operator-helm.tgz";
+        final AsDeploymentItem dItemOne = new AsDeploymentItem().asDeploymentItemInstId(AS_DEPLOYMENT_ITEM_ONE_INST_ID)
+                .asInst(asInst).status(State.INSTANTIATED).name("sampleapp-db").itemId("1").deploymentOrder(1)
+                .artifactFilePath(helmFile1).createTime(LocalDateTime.now()).lastUpdateTime(LocalDateTime.now())
+                .releaseName("testOne");
+
+        final String helmFile2 = "Artifacts/Deployment/HELM/sampleapp-services-helm.tgz";
+        final AsDeploymentItem dItemTwo = new AsDeploymentItem().asDeploymentItemInstId(AS_DEPLOYMENT_ITEM_TWO_INST_ID)
+                .asInst(asInst).status(State.INSTANTIATED).name("sampleapp-services").itemId("2").deploymentOrder(2)
+                .artifactFilePath(helmFile2).createTime(LocalDateTime.now()).lastUpdateTime(LocalDateTime.now())
+                .releaseName("testTwo");
+
+        asInst.asdeploymentItems(dItemOne);
+        asInst.asdeploymentItems(dItemTwo);
+        databaseServiceProvider.saveAsInst(asInst);
+        createKubeConfigFile(asInst);
+    }
+
+    private void mockKubernetesClientEndpoint() {
+
+        wireMockServer.stubFor(get(urlMatching("/apis/batch/v1/jobs\\?labelSelector.*&watch=false"))
+                .willReturn(aResponse().withBody(getJobList()).withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)));
+
+        wireMockServer.stubFor(get(urlMatching("/api/v1/pods\\?labelSelector.*&watch=false"))
+                .willReturn(aResponse().withBody(getPodList()).withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)));
+
+        wireMockServer.stubFor(get(urlMatching("/api/v1/services\\?labelSelector.*&watch=false"))
+                .willReturn(aResponse().withBody(getServiceList()).withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)));
+
+        wireMockServer.stubFor(get(urlMatching("/apis/apps/v1/deployments\\?labelSelector.*&watch=false")).willReturn(
+                aResponse().withBody(getDeploymentList()).withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)));
+
+        wireMockServer.stubFor(get(urlMatching("/apis/apps/v1/daemonsets\\?labelSelector.*&watch=false"))
+                .willReturn(aResponse().withBody(getDaemonList()).withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)));
+
+        wireMockServer.stubFor(get(urlMatching("/apis/apps/v1/replicasets\\?labelSelector.*&watch=false")).willReturn(
+                aResponse().withBody(getReplicaSetList()).withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)));
+
+        wireMockServer.stubFor(get(urlMatching("/apis/apps/v1/statefulsets\\?labelSelector.*&watch=false")).willReturn(
+                aResponse().withBody(getStatefulSetList()).withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)));
+    }
+
+    private void mockAAIEndPoints() {
+
+        final String vnfEndPoint = "/aai/" + V19 + "/network/generic-vnfs/generic-vnf/" + AS_INST_ID;
+
+        wireMockServer.stubFor(get(urlMatching(vnfEndPoint)).willReturn(
+                aResponse().withBody(gson.toJson(getGenericVnf())).withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)));
+        wireMockServer.stubFor(post(urlMatching(vnfEndPoint)).willReturn(ok()));
+    }
+
+    private String getServiceList() {
+        final V1ServiceList v1SeviceList = new V1ServiceList();
+        v1SeviceList.setApiVersion("v1");
+        v1SeviceList.setKind("ServiceList");
+        return gson.toJson(v1SeviceList);
+    }
+
+    private String getPodList() {
+        final V1PodList v1PodList = new V1PodList();
+        v1PodList.setApiVersion("v1");
+        v1PodList.setKind("PodList");
+        return gson.toJson(v1PodList);
+    }
+
+    private String getJobList() {
+        final V1JobList v1JobList = new V1JobList();
+        v1JobList.setApiVersion("v1");
+        v1JobList.setKind("JobList");
+        return gson.toJson(v1JobList);
+    }
+
+    private String getDeploymentList() {
+        final V1DeploymentList v1DeploymentList = new V1DeploymentList();
+        v1DeploymentList.setApiVersion("v1");
+        v1DeploymentList.setKind("DeploymentList");
+        return gson.toJson(v1DeploymentList);
+    }
+
+    private String getDaemonList() {
+        final V1DaemonSetList v1DaemonSetList = new V1DaemonSetList();
+        v1DaemonSetList.setApiVersion("v1");
+        v1DaemonSetList.setKind("DeploymentList");
+        return gson.toJson(v1DaemonSetList);
+    }
+
+    private String getStatefulSetList() {
+        final V1StatefulSetList v1StatefulSetList = new V1StatefulSetList();
+        v1StatefulSetList.setApiVersion("v1");
+        v1StatefulSetList.setKind("DeploymentList");
+        return gson.toJson(v1StatefulSetList);
+    }
+
+    private String getReplicaSetList() {
+        final V1ReplicaSetList v1ReplicaSetList = new V1ReplicaSetList();
+        v1ReplicaSetList.setApiVersion("v1");
+        v1ReplicaSetList.setKind("DeploymentList");
+        return gson.toJson(v1ReplicaSetList);
+    }
+
+    private GenericVnf getGenericVnf() {
+        final GenericVnf vnf = new GenericVnf();
+        vnf.setVnfId(AS_INST_ID);
+        vnf.setOrchestrationStatus(OrchestrationStatusEnum.ACTIVATED.getValue());
+        vnf.setResourceVersion("12345");
+        return vnf;
+    }
+
+}