Use distribution json for workflow install

Use distribution json for workflow install

Change-Id: I2eec3700d0ba92794b6ca11bd43683d91fb480ee
Issue-ID: SO-1726
Signed-off-by: Kuleshov, Elena <evn@att.com>
diff --git a/asdc-controller/src/main/java/org/onap/so/asdc/client/ASDCConfiguration.java b/asdc-controller/src/main/java/org/onap/so/asdc/client/ASDCConfiguration.java
index e2c358a..2eace75 100644
--- a/asdc-controller/src/main/java/org/onap/so/asdc/client/ASDCConfiguration.java
+++ b/asdc-controller/src/main/java/org/onap/so/asdc/client/ASDCConfiguration.java
@@ -55,7 +55,7 @@
     public static final String HEAT_VOL = "HEAT_VOL";
     public static final String OTHER = "OTHER";
     public static final String TOSCA_CSAR = "TOSCA_CSAR";
-    public static final String WORKFLOWS = "Workflows";
+    public static final String WORKFLOW = "WORKFLOW";
     public static final String VF_MODULES_METADATA = "VF_MODULES_METADATA";
 
     private static final String[] SUPPORTED_ARTIFACT_TYPES =
diff --git a/asdc-controller/src/main/java/org/onap/so/asdc/client/ASDCController.java b/asdc-controller/src/main/java/org/onap/so/asdc/client/ASDCController.java
index f2e875f..9b838c4 100644
--- a/asdc-controller/src/main/java/org/onap/so/asdc/client/ASDCController.java
+++ b/asdc-controller/src/main/java/org/onap/so/asdc/client/ASDCController.java
@@ -47,6 +47,7 @@
 import org.onap.sdc.impl.DistributionClientFactory;
 import org.onap.sdc.utils.DistributionActionResultEnum;
 import org.onap.sdc.utils.DistributionStatusEnum;
+import org.onap.so.asdc.activity.DeployActivitySpecs;
 import org.onap.so.asdc.client.exceptions.ASDCControllerException;
 import org.onap.so.asdc.client.exceptions.ASDCDownloadException;
 import org.onap.so.asdc.client.exceptions.ASDCParametersException;
@@ -57,7 +58,6 @@
 import org.onap.so.asdc.installer.ResourceType;
 import org.onap.so.asdc.installer.ToscaResourceStructure;
 import org.onap.so.asdc.installer.VfResourceStructure;
-import org.onap.so.asdc.installer.bpmn.BpmnInstaller;
 import org.onap.so.asdc.installer.heat.ToscaResourceInstaller;
 import org.onap.so.asdc.tenantIsolation.DistributionStatus;
 import org.onap.so.asdc.tenantIsolation.WatchdogDistribution;
@@ -89,9 +89,6 @@
     private ToscaResourceInstaller toscaInstaller;
 
     @Autowired
-    private BpmnInstaller bpmnInstaller;
-
-    @Autowired
     private WatchdogDistributionStatusRepository wdsRepo;
 
     @Autowired
@@ -110,6 +107,9 @@
     @Autowired
     private WatchdogDistribution wd;
 
+    @Autowired
+    DeployActivitySpecs deployActivitySpecs;
+
     public int getNbOfNotificationsOngoing() {
         return nbOfNotificationsOngoing;
     }
@@ -668,9 +668,6 @@
                     msoConfigPath + "/ASDC/" + iArtifact.getArtifactVersion() + "/" + iArtifact.getArtifactName();
             File csarFile = new File(filePath);
             String csarFilePath = csarFile.getAbsolutePath();
-            if (bpmnInstaller.containsWorkflows(csarFilePath)) {
-                bpmnInstaller.installBpmn(csarFilePath);
-            }
 
             for (IResourceInstance resource : iNotif.getResources()) {
 
@@ -679,7 +676,7 @@
 
                 logger.info("Processing Resource Type: {}, Model UUID: {}", resourceType, resource.getResourceUUID());
 
-                if ("VF".equals(resourceType) && !"Allotted Resource".equalsIgnoreCase(category)) {
+                if ("VF".equals(resourceType)) {
                     resourceStructure = new VfResourceStructure(iNotif, resource);
                 } else if ("PNF".equals(resourceType)) {
                     resourceStructure = new PnfResourceStructure(iNotif, resource);
@@ -697,7 +694,7 @@
                         logger.debug("Processing Resource Type: " + resourceType + " and Model UUID: "
                                 + resourceStructure.getResourceInstance().getResourceUUID());
 
-                        if ("VF".equals(resourceType) && !"Allotted Resource".equalsIgnoreCase(category)) {
+                        if ("VF".equals(resourceType)) {
                             hasVFResource = true;
                             for (IArtifactInfo artifact : resource.getArtifacts()) {
                                 IDistributionClientDownloadResult resultArtifact =
@@ -711,8 +708,15 @@
                                                 .dumpVfModuleMetaDataList(((VfResourceStructure) resourceStructure)
                                                         .decodeVfModuleArtifact(resultArtifact.getArtifactPayload())));
                                     }
-                                    resourceStructure.addArtifactToStructure(distributionClient, artifact,
-                                            resultArtifact);
+                                    if (!ASDCConfiguration.WORKFLOW.equals(artifact.getArtifactType())) {
+                                        resourceStructure.addArtifactToStructure(distributionClient, artifact,
+                                                resultArtifact);
+                                    } else {
+                                        writeArtifactToFile(artifact, resultArtifact);
+                                        logger.debug(
+                                                "Adding workflow artifact to structure: " + artifact.getArtifactName());
+                                        resourceStructure.addWorkflowArtifactToStructure(artifact, resultArtifact);
+                                    }
                                 }
                             }
 
@@ -801,7 +805,7 @@
                             "processCsarServiceArtifacts", ErrorCode.BusinessProcesssError.getValue(),
                             "Exception in processCsarServiceArtifacts", e);
                 }
-            } else if (artifact.getArtifactType().equals(ASDCConfiguration.WORKFLOWS)) {
+            } else if (artifact.getArtifactType().equals(ASDCConfiguration.WORKFLOW)) {
 
                 try {
 
diff --git a/asdc-controller/src/main/java/org/onap/so/asdc/installer/PnfResourceStructure.java b/asdc-controller/src/main/java/org/onap/so/asdc/installer/PnfResourceStructure.java
index 8aa9684..2a6e77e 100644
--- a/asdc-controller/src/main/java/org/onap/so/asdc/installer/PnfResourceStructure.java
+++ b/asdc-controller/src/main/java/org/onap/so/asdc/installer/PnfResourceStructure.java
@@ -39,6 +39,12 @@
     }
 
     @Override
+    public void addWorkflowArtifactToStructure(IArtifactInfo artifactinfo,
+            IDistributionClientDownloadResult clientResult) throws UnsupportedEncodingException {
+
+    }
+
+    @Override
     public void prepareInstall() throws ArtifactInstallerException {
 
     }
diff --git a/asdc-controller/src/main/java/org/onap/so/asdc/installer/ResourceStructure.java b/asdc-controller/src/main/java/org/onap/so/asdc/installer/ResourceStructure.java
index 9965a05..8be3d6b 100644
--- a/asdc-controller/src/main/java/org/onap/so/asdc/installer/ResourceStructure.java
+++ b/asdc-controller/src/main/java/org/onap/so/asdc/installer/ResourceStructure.java
@@ -68,10 +68,16 @@
      */
     protected final Map<String, VfModuleArtifact> artifactsMapByUUID;
 
+    /**
+     * The list of workflow artifacts existing in this resource
+     */
+    protected final Map<String, WorkflowArtifact> workflowArtifactsMapByUUID;
+
     public ResourceStructure(INotificationData notificationData, IResourceInstance resourceInstance) {
         this.notificationData = notificationData;
         this.resourceInstance = resourceInstance;
         artifactsMapByUUID = new HashMap<>();
+        workflowArtifactsMapByUUID = new HashMap<>();
     }
 
     /**
@@ -85,6 +91,9 @@
     public abstract void addArtifactToStructure(IDistributionClient distributionClient, IArtifactInfo artifactinfo,
             IDistributionClientDownloadResult clientResult) throws UnsupportedEncodingException;
 
+    public abstract void addWorkflowArtifactToStructure(IArtifactInfo artifactinfo,
+            IDistributionClientDownloadResult clientResult) throws UnsupportedEncodingException;
+
     /**
      * Prepare the resource for installation.
      *
@@ -144,4 +153,8 @@
         return artifactsMapByUUID;
     }
 
+    public Map<String, WorkflowArtifact> getWorkflowArtifactsMapByUUID() {
+        return workflowArtifactsMapByUUID;
+    }
+
 }
diff --git a/asdc-controller/src/main/java/org/onap/so/asdc/installer/VfResourceStructure.java b/asdc-controller/src/main/java/org/onap/so/asdc/installer/VfResourceStructure.java
index 62408be..16e9fda 100644
--- a/asdc-controller/src/main/java/org/onap/so/asdc/installer/VfResourceStructure.java
+++ b/asdc-controller/src/main/java/org/onap/so/asdc/installer/VfResourceStructure.java
@@ -98,6 +98,12 @@
         }
     }
 
+    public void addWorkflowArtifactToStructure(IArtifactInfo artifactinfo,
+            IDistributionClientDownloadResult clientResult) throws UnsupportedEncodingException {
+        WorkflowArtifact workflowArtifact = new WorkflowArtifact(artifactinfo, clientResult);
+        workflowArtifactsMapByUUID.put(artifactinfo.getArtifactUUID(), workflowArtifact);
+    }
+
     protected void addArtifactByType(IArtifactInfo artifactinfo, IDistributionClientDownloadResult clientResult,
             VfModuleArtifact vfModuleArtifact) throws UnsupportedEncodingException {
 
diff --git a/asdc-controller/src/main/java/org/onap/so/asdc/installer/WorkflowArtifact.java b/asdc-controller/src/main/java/org/onap/so/asdc/installer/WorkflowArtifact.java
new file mode 100644
index 0000000..83b5614
--- /dev/null
+++ b/asdc-controller/src/main/java/org/onap/so/asdc/installer/WorkflowArtifact.java
@@ -0,0 +1,65 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.asdc.installer;
+
+
+import java.io.UnsupportedEncodingException;
+import org.onap.so.db.catalog.beans.HeatEnvironment;
+import org.onap.so.db.catalog.beans.HeatFiles;
+import org.onap.so.db.catalog.beans.HeatTemplate;
+import org.onap.sdc.api.notification.IArtifactInfo;
+import org.onap.sdc.api.results.IDistributionClientDownloadResult;
+
+/**
+ * The structure that contains the artifactInfo and its associated DownloadedResult.
+ *
+ */
+public final class WorkflowArtifact {
+    private final IArtifactInfo artifactInfo;
+    private int deployedInDb = 0;
+    private final String result;
+
+    public WorkflowArtifact(IArtifactInfo artifactinfo, IDistributionClientDownloadResult clientResult)
+            throws UnsupportedEncodingException {
+        result = new String(clientResult.getArtifactPayload(), "UTF-8");
+        artifactInfo = artifactinfo;
+
+    }
+
+    public IArtifactInfo getArtifactInfo() {
+        return artifactInfo;
+    }
+
+    public String getResult() {
+        return result;
+    }
+
+    public int getDeployedInDb() {
+        return deployedInDb;
+    }
+
+    public void incrementDeployedInDB() {
+        ++deployedInDb;
+    }
+
+
+
+}
diff --git a/asdc-controller/src/main/java/org/onap/so/asdc/installer/bpmn/BpmnInstaller.java b/asdc-controller/src/main/java/org/onap/so/asdc/installer/bpmn/BpmnInstaller.java
index c98fb9b..7945ad0 100644
--- a/asdc-controller/src/main/java/org/onap/so/asdc/installer/bpmn/BpmnInstaller.java
+++ b/asdc-controller/src/main/java/org/onap/so/asdc/installer/bpmn/BpmnInstaller.java
@@ -58,7 +58,7 @@
     protected static final Logger logger = LoggerFactory.getLogger(BpmnInstaller.class);
     private static final String BPMN_SUFFIX = ".bpmn";
     private static final String CAMUNDA_URL = "mso.camundaURL";
-    private static final String CREATE_DEPLOYMENT_PATH = "/sobpmnengine/deployment/create";
+    private static final String CREATE_DEPLOYMENT_PATH = "sobpmnengine/deployment/create";
 
     @Autowired
     private Environment env;
@@ -78,7 +78,7 @@
                         Path p = Paths.get(name);
                         String fileName = p.getFileName().toString();
                         extractBpmnFileFromCsar(csarFile, fileName);
-                        HttpResponse response = sendDeploymentRequest(fileName);
+                        HttpResponse response = sendDeploymentRequest(fileName, "");
                         logger.debug("Response status line: {}", response.getStatusLine());
                         logger.debug("Response entity: {}", response.getEntity().toString());
                         if (response.getStatusLine().getStatusCode() != 200) {
@@ -125,21 +125,21 @@
         return workflowsInCsar;
     }
 
-    protected HttpResponse sendDeploymentRequest(String bpmnFileName) throws Exception {
+    protected HttpResponse sendDeploymentRequest(String bpmnFileName, String version) throws Exception {
         HttpClient client = HttpClientBuilder.create().build();
         URI deploymentUri = new URI(this.env.getProperty(CAMUNDA_URL) + CREATE_DEPLOYMENT_PATH);
         HttpPost post = new HttpPost(deploymentUri);
         RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(1000000).setConnectTimeout(1000)
                 .setConnectionRequestTimeout(1000).build();
         post.setConfig(requestConfig);
-        HttpEntity requestEntity = buildMimeMultipart(bpmnFileName);
+        HttpEntity requestEntity = buildMimeMultipart(bpmnFileName, version);
         post.setEntity(requestEntity);
         return client.execute(post);
     }
 
-    protected HttpEntity buildMimeMultipart(String bpmnFileName) throws Exception {
+    protected HttpEntity buildMimeMultipart(String bpmnFileName, String version) throws Exception {
         FileInputStream bpmnFileStream = new FileInputStream(
-                Paths.get(System.getProperty("mso.config.path"), "ASDC", bpmnFileName).normalize().toString());
+                Paths.get(System.getProperty("mso.config.path"), "ASDC", version, bpmnFileName).normalize().toString());
 
         byte[] bytesToSend = IOUtils.toByteArray(bpmnFileStream);
         HttpEntity requestEntity =
diff --git a/asdc-controller/src/main/java/org/onap/so/asdc/installer/bpmn/WorkflowResource.java b/asdc-controller/src/main/java/org/onap/so/asdc/installer/bpmn/WorkflowResource.java
new file mode 100644
index 0000000..daeda2f
--- /dev/null
+++ b/asdc-controller/src/main/java/org/onap/so/asdc/installer/bpmn/WorkflowResource.java
@@ -0,0 +1,215 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright (c) 2019 Samsung
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.asdc.installer.bpmn;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.http.HttpResponse;
+import org.onap.sdc.api.notification.IArtifactInfo;
+import org.onap.so.asdc.installer.VfResourceStructure;
+import org.onap.so.asdc.installer.WorkflowArtifact;
+import org.onap.so.db.catalog.beans.ActivitySpec;
+import org.onap.so.db.catalog.beans.VnfResourceWorkflow;
+import org.onap.so.db.catalog.beans.Workflow;
+import org.onap.so.db.catalog.beans.WorkflowActivitySpecSequence;
+import org.onap.so.db.catalog.data.repository.ActivitySpecRepository;
+import org.onap.so.db.catalog.data.repository.WorkflowRepository;
+import org.onap.so.logger.ErrorCode;
+import org.onap.so.logger.MessageEnum;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class WorkflowResource {
+    protected static final Logger logger = LoggerFactory.getLogger(WorkflowResource.class);
+
+    private static final String pattern = ".*\\\"activity:(.*)\\\" .*";
+    private static final String TARGET_RESOURCE_VNF = "vnf";
+    private static final String SOURCE_SDC = "sdc";
+    private static final String BPMN_SUFFIX = ".bpmn";
+
+    @Autowired
+    protected WorkflowRepository workflowRepo;
+
+    @Autowired
+    protected ActivitySpecRepository activityRepo;
+
+    @Autowired
+    private BpmnInstaller bpmnInstaller;
+
+    public void processWorkflows(VfResourceStructure vfResourceStructure) throws Exception {
+        Map<String, WorkflowArtifact> artifactsMapByUUID = vfResourceStructure.getWorkflowArtifactsMapByUUID();
+        String vfResourceModelUuid = vfResourceStructure.getResourceInstance().getResourceUUID();
+        for (String uuid : artifactsMapByUUID.keySet()) {
+            WorkflowArtifact artifactToInstall = artifactsMapByUUID.get(uuid);
+            if (isLatestVersionAvailable(artifactsMapByUUID, artifactToInstall)) {
+                logger.debug("Installing the BPMN: " + artifactToInstall.getArtifactInfo().getArtifactName());
+                deployWorkflowResourceToCamunda(artifactToInstall);
+                installWorkflowResource(artifactToInstall, vfResourceModelUuid);
+            } else {
+                logger.debug("Skipping installing - not the latest version: "
+                        + artifactToInstall.getArtifactInfo().getArtifactName());
+            }
+        }
+    }
+
+    protected void deployWorkflowResourceToCamunda(WorkflowArtifact artifact) throws Exception {
+        String bpmnName = artifact.getArtifactInfo().getArtifactName();
+        String version = artifact.getArtifactInfo().getArtifactVersion();
+        logger.debug("BPMN Name: " + bpmnName);
+        try {
+            HttpResponse response = bpmnInstaller.sendDeploymentRequest(bpmnName, version);
+            logger.debug("Response status line: {}", response.getStatusLine());
+            logger.debug("Response entity: {}", response.getEntity().toString());
+            if (response.getStatusLine().getStatusCode() != 200) {
+                logger.debug("Failed deploying BPMN {}", bpmnName);
+                logger.error("{} {} {} {} {} {}", MessageEnum.ASDC_ARTIFACT_NOT_DEPLOYED_DETAIL.toString(), bpmnName,
+                        bpmnName, Integer.toString(response.getStatusLine().getStatusCode()),
+                        ErrorCode.DataError.getValue(), "ASDC BPMN deploy failed");
+                throw (new Exception("Error from Camunda on deploying the BPMN: " + bpmnName));
+            } else {
+                logger.debug("Successfully deployed to Camunda: {}", bpmnName);
+            }
+        } catch (Exception e) {
+            logger.debug("Exception :", e);
+            logger.error("{} {} {} {} {}", MessageEnum.ASDC_ARTIFACT_NOT_DEPLOYED_DETAIL.toString(), bpmnName,
+                    e.getMessage(), ErrorCode.DataError.getValue(), "ASDC BPMN deploy failed");
+            throw e;
+        }
+    }
+
+    protected void installWorkflowResource(WorkflowArtifact artifact, String vfResourceModelUuid) throws Exception {
+        IArtifactInfo artifactInfo = artifact.getArtifactInfo();
+
+        Workflow workflow = new Workflow();
+
+        workflow.setArtifactChecksum(artifactInfo.getArtifactChecksum());
+        workflow.setArtifactName(artifactInfo.getArtifactName());
+        workflow.setArtifactUUID(artifactInfo.getArtifactUUID());
+        workflow.setBody(artifact.getResult());
+        workflow.setDescription(artifactInfo.getArtifactDescription());
+        workflow.setName(getWorkflowNameFromArtifactName(artifactInfo.getArtifactName()));
+        workflow.setResourceTarget(TARGET_RESOURCE_VNF);
+        workflow.setSource(SOURCE_SDC);
+        workflow.setTimeoutMinutes(artifactInfo.getArtifactTimeout());
+        workflow.setOperationName(getWorkflowNameFromArtifactName(artifactInfo.getArtifactName()));
+        workflow.setVersion(getWorkflowVersionFromArtifactName(artifactInfo.getArtifactName()));
+
+        VnfResourceWorkflow vnfResourceWorkflow = new VnfResourceWorkflow();
+        vnfResourceWorkflow.setVnfResourceModelUUID(vfResourceModelUuid);
+        List<VnfResourceWorkflow> vnfResourceWorkflows = new ArrayList<VnfResourceWorkflow>();
+        vnfResourceWorkflows.add(vnfResourceWorkflow);
+
+        workflow.setVnfResourceWorkflow(vnfResourceWorkflows);
+
+        List<String> activityNames = getActivityNameList(artifact.getResult());
+        List<WorkflowActivitySpecSequence> wfss = getWorkflowActivitySpecSequence(activityNames);
+        workflow.setWorkflowActivitySpecSequence(wfss);
+
+        workflowRepo.save(workflow);
+
+    }
+
+    protected boolean isLatestVersionAvailable(Map<String, WorkflowArtifact> artifactsMapByUUID,
+            WorkflowArtifact artifact) {
+        String workflowName = getWorkflowNameFromArtifactName(artifact.getArtifactInfo().getArtifactName());
+        Double workflowVersion = getWorkflowVersionFromArtifactName(artifact.getArtifactInfo().getArtifactName());
+        if (workflowVersion == null) {
+            workflowVersion = 0.0;
+        }
+        for (WorkflowArtifact artifactInMap : artifactsMapByUUID.values()) {
+            Double versionInMap = getWorkflowVersionFromArtifactName(artifactInMap.getArtifactInfo().getArtifactName());
+            if (versionInMap == null) {
+                versionInMap = 0.0;
+            }
+            if (workflowName.equals(getWorkflowNameFromArtifactName(artifactInMap.getArtifactInfo().getArtifactName()))
+                    && Double.compare(workflowVersion, versionInMap) < 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    protected List<String> getActivityNameList(String bpmnContent) {
+        List<String> activityNameList = new ArrayList<String>();
+
+        Pattern p = Pattern.compile(pattern);
+        Matcher m = p.matcher(bpmnContent);
+        while (m.find()) {
+            activityNameList.add(m.group(1));
+        }
+        return activityNameList;
+    }
+
+    protected List<WorkflowActivitySpecSequence> getWorkflowActivitySpecSequence(List<String> activityNames)
+            throws Exception {
+        if (activityNames == null || activityNames.size() == 0) {
+            return null;
+        }
+        List<WorkflowActivitySpecSequence> workflowActivitySpecs = new ArrayList<WorkflowActivitySpecSequence>();
+        for (String activityName : activityNames) {
+            ActivitySpec activitySpec = activityRepo.findByName(activityName);
+            if (activitySpec != null) {
+                WorkflowActivitySpecSequence workflowActivitySpec = new WorkflowActivitySpecSequence();
+                workflowActivitySpec.setActivitySpec(activitySpec);
+                workflowActivitySpecs.add(workflowActivitySpec);
+            }
+        }
+        return workflowActivitySpecs;
+    }
+
+    public String getWorkflowNameFromArtifactName(String artifactName) {
+        if (artifactName == null) {
+            return null;
+        } else {
+            if (artifactName.contains(BPMN_SUFFIX)) {
+                return artifactName.substring(0, artifactName.lastIndexOf(BPMN_SUFFIX)).split("-")[0];
+            } else {
+                return artifactName.split("-")[0];
+            }
+        }
+    }
+
+    public Double getWorkflowVersionFromArtifactName(String artifactName) {
+        if (artifactName == null) {
+            return null;
+        } else {
+            String[] workflowNameParts = null;
+            if (artifactName.contains(BPMN_SUFFIX)) {
+                workflowNameParts = artifactName.substring(0, artifactName.lastIndexOf(BPMN_SUFFIX)).split("-");
+            } else {
+                workflowNameParts = artifactName.split("-");
+            }
+            if (workflowNameParts.length < 2) {
+                return null;
+            } else {
+                return Double.valueOf(workflowNameParts[1].replaceAll("_", "."));
+            }
+        }
+    }
+}
diff --git a/asdc-controller/src/main/java/org/onap/so/asdc/installer/heat/ToscaResourceInstaller.java b/asdc-controller/src/main/java/org/onap/so/asdc/installer/heat/ToscaResourceInstaller.java
index d3eab9a..23c31f3 100644
--- a/asdc-controller/src/main/java/org/onap/so/asdc/installer/heat/ToscaResourceInstaller.java
+++ b/asdc-controller/src/main/java/org/onap/so/asdc/installer/heat/ToscaResourceInstaller.java
@@ -70,6 +70,7 @@
 import org.onap.so.asdc.installer.VfModuleArtifact;
 import org.onap.so.asdc.installer.VfModuleStructure;
 import org.onap.so.asdc.installer.VfResourceStructure;
+import org.onap.so.asdc.installer.bpmn.WorkflowResource;
 import org.onap.so.asdc.util.YamlEditor;
 import org.onap.so.db.catalog.beans.AllottedResource;
 import org.onap.so.db.catalog.beans.AllottedResourceCustomization;
@@ -246,6 +247,9 @@
     @Autowired
     protected PnfCustomizationRepository pnfCustomizationRepository;
 
+    @Autowired
+    protected WorkflowResource workflowResource;
+
     protected static final Logger logger = LoggerFactory.getLogger(ToscaResourceInstaller.class);
 
     public boolean isResourceAlreadyDeployed(ResourceStructure vfResourceStruct, boolean serviceDeployed)
@@ -400,6 +404,7 @@
                         vfCustomizationCategory);
             }
 
+            workflowResource.processWorkflows(vfResourceStructure);
             processResourceSequence(toscaResourceStruct, service);
             List<NodeTemplate> allottedResourceList = toscaResourceStruct.getSdcCsarHelper().getAllottedResources();
             processAllottedResources(toscaResourceStruct, service, allottedResourceList);
diff --git a/asdc-controller/src/test/java/org/onap/so/asdc/client/test/rest/ASDCRestInterfaceTest.java b/asdc-controller/src/test/java/org/onap/so/asdc/client/test/rest/ASDCRestInterfaceTest.java
index 2e5ad13..ac107f6 100644
--- a/asdc-controller/src/test/java/org/onap/so/asdc/client/test/rest/ASDCRestInterfaceTest.java
+++ b/asdc-controller/src/test/java/org/onap/so/asdc/client/test/rest/ASDCRestInterfaceTest.java
@@ -22,12 +22,15 @@
 
 import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
 import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
 import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
 import static com.shazam.shazamcrest.MatcherAssert.assertThat;
 import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.HashSet;
 import java.util.Set;
 import javax.transaction.Transactional;
@@ -43,9 +46,11 @@
 import org.onap.so.db.catalog.beans.AllottedResource;
 import org.onap.so.db.catalog.beans.AllottedResourceCustomization;
 import org.onap.so.db.catalog.beans.Service;
+import org.onap.so.db.catalog.beans.Workflow;
 import org.onap.so.db.catalog.data.repository.AllottedResourceRepository;
 import org.onap.so.db.catalog.data.repository.NetworkResourceRepository;
 import org.onap.so.db.catalog.data.repository.ServiceRepository;
+import org.onap.so.db.catalog.data.repository.WorkflowRepository;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.web.client.TestRestTemplate;
 import org.springframework.boot.web.server.LocalServerPort;
@@ -67,6 +72,9 @@
     private NetworkResourceRepository networkRepo;
 
     @Autowired
+    private WorkflowRepository workflowRepo;
+
+    @Autowired
     private ASDCRestInterface asdcRestInterface;
 
     private TestRestTemplate restTemplate = new TestRestTemplate("test", "test");
@@ -97,6 +105,10 @@
         wireMockServer.stubFor(post(urlPathMatching("/aai/.*"))
                 .willReturn(aResponse().withStatus(200).withHeader("Content-Type", "application/json")));
 
+        wireMockServer.stubFor(post(urlPathMatching("/v1.0/activity-spec"))
+                .willReturn(aResponse().withHeader("Content-Type", "application/json")
+                        .withStatus(org.springframework.http.HttpStatus.ACCEPTED.value())));
+
         ObjectMapper mapper = new ObjectMapper();
         NotificationDataImpl request =
                 mapper.readValue(new File("src/test/resources/resource-examples/allottedresource/notif-portm.json"),
@@ -146,6 +158,10 @@
         wireMockServer.stubFor(post(urlPathMatching("/aai/.*"))
                 .willReturn(aResponse().withStatus(200).withHeader("Content-Type", "application/json")));
 
+        wireMockServer.stubFor(post(urlPathMatching("/v1.0/activity-spec"))
+                .willReturn(aResponse().withHeader("Content-Type", "application/json")
+                        .withStatus(org.springframework.http.HttpStatus.ACCEPTED.value())));
+
         ObjectMapper mapper = new ObjectMapper();
         NotificationDataImpl request = mapper.readValue(
                 new File("src/test/resources/resource-examples/vFW/notification.json"), NotificationDataImpl.class);
@@ -176,15 +192,58 @@
     }
 
     @Test
+    @Transactional
+    public void testWorkflowDistribution() throws Exception {
+
+        wireMockServer.stubFor(post(urlPathMatching("/aai/.*"))
+                .willReturn(aResponse().withStatus(200).withHeader("Content-Type", "application/json")));
+
+        wireMockServer.stubFor(post(urlPathMatching("/v1.0/activity-spec"))
+                .willReturn(aResponse().withHeader("Content-Type", "application/json")
+                        .withStatus(org.springframework.http.HttpStatus.ACCEPTED.value())));
+
+        wireMockServer.stubFor(
+                post(urlPathEqualTo("/sobpmnengine/deployment/create")).willReturn(aResponse().withStatus(200)));
+
+        ObjectMapper mapper = new ObjectMapper();
+        NotificationDataImpl request = mapper.readValue(
+                new File("src/test/resources/resource-examples/WorkflowBpmn/workflow-distribution.json"),
+                NotificationDataImpl.class);
+        headers.add("resource-location", "src/test/resources/resource-examples/WorkflowBpmn/");
+        HttpEntity<NotificationDataImpl> entity = new HttpEntity<NotificationDataImpl>(request, headers);
+
+        ResponseEntity<String> response = restTemplate.exchange(createURLWithPort("test/treatNotification/v1"),
+                HttpMethod.POST, entity, String.class);
+
+        assertEquals(Response.Status.OK.getStatusCode(), response.getStatusCode().value());
+
+        Workflow actualResponse = workflowRepo.findByArtifactUUID("a90f8eaa-7c20-422f-8c81-aacbca6fb9e7");
+
+        if (actualResponse == null)
+            throw new Exception("No Workflow Written to database");
+
+        String expectedBody = new String(
+                Files.readAllBytes(Paths.get("src/test/resources/resource-examples/WorkflowBpmn/TestWF2-1_0.bpmn")));
+        assertEquals(actualResponse.getArtifactChecksum(), "ZjUzNjg1NDMyMTc4MWJmZjFlNDcyOGQ0Zjc1YWQwYzQ\u003d");
+        assertEquals(actualResponse.getArtifactName(), "TestWF2-1_0.bpmn");
+        assertEquals(actualResponse.getDescription(), "Workflow Artifact Description");
+        assertEquals(actualResponse.getBody(), expectedBody);
+
+        Workflow shouldNotBeFound = workflowRepo.findByArtifactUUID("f27066a1-c3a7-4672-b02e-1251b74b7b71");
+        assertNull(shouldNotBeFound);
+    }
+
+    @Test
     public void invokeASDCStatusDataNullTest() {
         String request = "";
+        wireMockServer.stubFor(post(urlPathMatching("/v1.0/activity-spec"))
+                .willReturn(aResponse().withHeader("Content-Type", "application/json")
+                        .withStatus(org.springframework.http.HttpStatus.ACCEPTED.value())));
         Response response = asdcRestInterface.invokeASDCStatusData(request);
         assertNull(response);
 
     }
 
-
-
     protected String createURLWithPort(String uri) {
         return "http://localhost:" + port + uri;
     }
diff --git a/asdc-controller/src/test/java/org/onap/so/asdc/installer/bpmn/BpmnInstallerTest.java b/asdc-controller/src/test/java/org/onap/so/asdc/installer/bpmn/BpmnInstallerTest.java
index 6efb04f..7071a68 100644
--- a/asdc-controller/src/test/java/org/onap/so/asdc/installer/bpmn/BpmnInstallerTest.java
+++ b/asdc-controller/src/test/java/org/onap/so/asdc/installer/bpmn/BpmnInstallerTest.java
@@ -81,7 +81,7 @@
     public void buildMimeMultiPart_Test() throws Exception {
         Path tempFilePath = Paths.get(tempDirectoryPath.toAbsolutePath().toString(), "TestBB.bpmn");
         Files.createFile(tempFilePath);
-        HttpEntity entity = bpmnInstaller.buildMimeMultipart("TestBB.bpmn");
+        HttpEntity entity = bpmnInstaller.buildMimeMultipart("TestBB.bpmn", "");
         String mimeMultipartBodyFilePath = "src/test/resources" + "/mime-multipart-body.txt";
 
         File mimeMultipartBody = new File(mimeMultipartBodyFilePath);
@@ -99,7 +99,7 @@
         HttpClient httpClient = mock(HttpClient.class);
         doReturn(response).when(httpClient).execute(any(HttpPost.class));
         bpmnInstallerSpy.installBpmn(TEST_CSAR);
-        verify(bpmnInstallerSpy, times(1)).sendDeploymentRequest(anyString());
+        verify(bpmnInstallerSpy, times(1)).sendDeploymentRequest(anyString(), anyString());
     }
 
     @Test
diff --git a/asdc-controller/src/test/java/org/onap/so/asdc/installer/bpmn/WorkflowResourceTest.java b/asdc-controller/src/test/java/org/onap/so/asdc/installer/bpmn/WorkflowResourceTest.java
new file mode 100644
index 0000000..e655245
--- /dev/null
+++ b/asdc-controller/src/test/java/org/onap/so/asdc/installer/bpmn/WorkflowResourceTest.java
@@ -0,0 +1,109 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright (c) 2019 Samsung
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.asdc.installer.bpmn;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import javax.transaction.Transactional;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.ProtocolVersion;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.message.BasicHttpResponse;
+import org.apache.http.message.BasicStatusLine;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.onap.sdc.api.notification.IArtifactInfo;
+
+@Transactional
+public class WorkflowResourceTest {
+
+    private WorkflowResource workflowResource = new WorkflowResource();
+
+    private static final String TEST_CSAR = "src/test/resources/resource-examples/WorkflowBpmn/service-CxSvc-csar.csar";
+    private Path tempDirectoryPath;
+
+    @Test
+    public void getActivityNameList_Test() throws Exception {
+        String bpmnContent = new String(Files
+                .readAllBytes(Paths.get("src/test/resources/resource-examples/WorkflowBpmn/TestBpmnFromSDC.bpmn")));
+        List<String> activityNames = workflowResource.getActivityNameList(bpmnContent);
+        assertEquals("VNFSetInMaintFlagActivity", activityNames.get(0));
+    }
+
+    @Test
+    public void getWorkflowNameStandard_Test() {
+        String workflowName = workflowResource.getWorkflowNameFromArtifactName("TestWF2-1_0.bpmn");
+        assertEquals("TestWF2", workflowName);
+    }
+
+    @Test
+    public void getWorkflowNameNoVersion_Test() {
+        String workflowName = workflowResource.getWorkflowNameFromArtifactName("TestWF2.bpmn");
+        assertEquals("TestWF2", workflowName);
+    }
+
+    @Test
+    public void getWorkflowNameNoSuffix_Test() {
+        String workflowName = workflowResource.getWorkflowNameFromArtifactName("TestWF2-1_0");
+        assertEquals("TestWF2", workflowName);
+    }
+
+    @Test
+    public void getWorkflowVersionStandard_Test() {
+        Double workflowVersion = workflowResource.getWorkflowVersionFromArtifactName("TestWF2-1_0.bpmn");
+        assertTrue(workflowVersion == 1.0);
+    }
+
+    @Test
+    public void getWorkflowVersionNoVersion_Test() {
+        Double workflowVersion = workflowResource.getWorkflowVersionFromArtifactName("TestWF2.bpmn");
+        assertNull(workflowVersion);
+    }
+
+    @Test
+    public void getWorkflowVersionNoSuffix_Test() {
+        Double workflowVersion = workflowResource.getWorkflowVersionFromArtifactName("TestWF2-1_0");
+        assertTrue(workflowVersion == 1.0);
+    }
+
+}
diff --git a/asdc-controller/src/test/resources/application-test.yaml b/asdc-controller/src/test/resources/application-test.yaml
index ec53649..9fa2055 100644
--- a/asdc-controller/src/test/resources/application-test.yaml
+++ b/asdc-controller/src/test/resources/application-test.yaml
@@ -66,6 +66,7 @@
     db:
       spring:
         endpoint: "http://localhost:"
+  camundaURL: http://localhost:${wiremock.server.port}/        
   db:
     auth: Basic YnBlbDptc28tZGItMTUwNyE=
   site-name: siteName
diff --git a/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/TestBpmnFromSDC.bpmn b/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/TestBpmnFromSDC.bpmn
new file mode 100644
index 0000000..f3a5c7c
--- /dev/null
+++ b/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/TestBpmnFromSDC.bpmn
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:bioc="http://bpmn.io/schema/bpmn/biocolor/1.0" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
+  <bpmn2:process id="customWorkflowtest1" name="TestBpmnFromSDC" isExecutable="true">
+    <bpmn2:extensionElements>
+      <camunda:inputOutput />
+    </bpmn2:extensionElements>
+    <bpmn2:startEvent id="StartEvent_0wtabee">
+      <bpmn2:outgoing>SequenceFlow_1v7ptqz</bpmn2:outgoing>
+    </bpmn2:startEvent>
+    <bpmn2:serviceTask id="Task_1kxbei4" name="VNFSetInMaintFlagActivity" implementation="activity:VNFSetInMaintFlagActivity" camunda:expression="${ExecuteActivity.execute(execution)}">
+      <bpmn2:extensionElements>
+        <camunda:inputOutput />
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>SequenceFlow_1v7ptqz</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_16i7mid</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:intermediateThrowEvent id="IntermediateThrowEvent_0tgyvzw">
+      <bpmn2:incoming>SequenceFlow_16i7mid</bpmn2:incoming>
+    </bpmn2:intermediateThrowEvent>
+    <bpmn2:sequenceFlow id="SequenceFlow_16i7mid" sourceRef="Task_1kxbei4" targetRef="IntermediateThrowEvent_0tgyvzw" />
+    <bpmn2:sequenceFlow id="SequenceFlow_1v7ptqz" sourceRef="StartEvent_0wtabee" targetRef="Task_1kxbei4" />
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="customWorkflowtest1">
+      <bpmndi:BPMNShape id="StartEvent_0wtabee_di" bpmnElement="StartEvent_0wtabee">
+        <dc:Bounds x="256" y="134" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ServiceTask_1cgg6ym_di" bpmnElement="Task_1kxbei4" bioc:fill="white">
+        <dc:Bounds x="386" y="112" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="IntermediateThrowEvent_0tgyvzw_di" bpmnElement="IntermediateThrowEvent_0tgyvzw">
+        <dc:Bounds x="536" y="134" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_16i7mid_di" bpmnElement="SequenceFlow_16i7mid">
+        <di:waypoint x="486" y="152" />
+        <di:waypoint x="536" y="152" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1v7ptqz_di" bpmnElement="SequenceFlow_1v7ptqz">
+        <di:waypoint x="292" y="152" />
+        <di:waypoint x="386" y="152" />
+      </bpmndi:BPMNEdge>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn2:definitions>
\ No newline at end of file
diff --git a/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/TestWF2-1_0.bpmn b/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/TestWF2-1_0.bpmn
new file mode 100644
index 0000000..11378cf
--- /dev/null
+++ b/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/TestWF2-1_0.bpmn
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="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" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
+  <bpmn2:process id="testwf2" name="TestWF2" isExecutable="true">
+    <bpmn2:extensionElements>
+      <camunda:inputOutput />
+    </bpmn2:extensionElements>
+    <bpmn2:endEvent id="EndEvent_1naezi3" />
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="testwf2">
+      <bpmndi:BPMNShape id="EndEvent_1naezi3_di" bpmnElement="EndEvent_1naezi3">
+        <dc:Bounds x="219" y="285" width="36" height="36" />
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn2:definitions>
diff --git a/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/sdc/v1/catalog/services/Testparentservice/1.0/resourceInstances/testvf0/artifacts/TestWF-1_0.bpmn b/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/sdc/v1/catalog/services/Testparentservice/1.0/resourceInstances/testvf0/artifacts/TestWF-1_0.bpmn
new file mode 100644
index 0000000..4e21a47
--- /dev/null
+++ b/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/sdc/v1/catalog/services/Testparentservice/1.0/resourceInstances/testvf0/artifacts/TestWF-1_0.bpmn
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="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" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
+  <bpmn2:process id="testwf" name="TestWF" isExecutable="true">
+    <bpmn2:extensionElements>
+      <camunda:inputOutput />
+    </bpmn2:extensionElements>
+    <bpmn2:startEvent id="StartEvent_1loupvi" />
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="testwf">
+      <bpmndi:BPMNShape id="StartEvent_1loupvi_di" bpmnElement="StartEvent_1loupvi">
+        <dc:Bounds x="274" y="212" width="36" height="36" />
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn2:definitions>
diff --git a/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/sdc/v1/catalog/services/Testparentservice/1.0/resourceInstances/testvf0/artifacts/TestWF-2_0.bpmn b/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/sdc/v1/catalog/services/Testparentservice/1.0/resourceInstances/testvf0/artifacts/TestWF-2_0.bpmn
new file mode 100644
index 0000000..e54d79a
--- /dev/null
+++ b/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/sdc/v1/catalog/services/Testparentservice/1.0/resourceInstances/testvf0/artifacts/TestWF-2_0.bpmn
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="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" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
+  <bpmn2:process id="testwf" name="TestWF" isExecutable="true">
+    <bpmn2:extensionElements>
+      <camunda:inputOutput />
+    </bpmn2:extensionElements>
+    <bpmn2:startEvent id="StartEvent_1loupvi" />
+    <bpmn2:startEvent id="StartEvent_0z42dnp" />
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="testwf">
+      <bpmndi:BPMNShape id="StartEvent_1loupvi_di" bpmnElement="StartEvent_1loupvi">
+        <dc:Bounds x="274" y="212" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="StartEvent_0z42dnp_di" bpmnElement="StartEvent_0z42dnp">
+        <dc:Bounds x="454" y="364" width="36" height="36" />
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn2:definitions>
diff --git a/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/sdc/v1/catalog/services/Testparentservice/1.0/resourceInstances/testvf0/artifacts/TestWF2-1_0.bpmn b/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/sdc/v1/catalog/services/Testparentservice/1.0/resourceInstances/testvf0/artifacts/TestWF2-1_0.bpmn
new file mode 100644
index 0000000..11378cf
--- /dev/null
+++ b/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/sdc/v1/catalog/services/Testparentservice/1.0/resourceInstances/testvf0/artifacts/TestWF2-1_0.bpmn
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="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" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
+  <bpmn2:process id="testwf2" name="TestWF2" isExecutable="true">
+    <bpmn2:extensionElements>
+      <camunda:inputOutput />
+    </bpmn2:extensionElements>
+    <bpmn2:endEvent id="EndEvent_1naezi3" />
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="testwf2">
+      <bpmndi:BPMNShape id="EndEvent_1naezi3_di" bpmnElement="EndEvent_1naezi3">
+        <dc:Bounds x="219" y="285" width="36" height="36" />
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn2:definitions>
diff --git a/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/service-Testparentservice-csar.csar b/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/service-Testparentservice-csar.csar
new file mode 100644
index 0000000..fe99318
--- /dev/null
+++ b/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/service-Testparentservice-csar.csar
Binary files differ
diff --git a/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/workflow-distribution.json b/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/workflow-distribution.json
new file mode 100644
index 0000000..9f49be5
--- /dev/null
+++ b/asdc-controller/src/test/resources/resource-examples/WorkflowBpmn/workflow-distribution.json
@@ -0,0 +1,76 @@
+{
+  "distributionID": "48cc0f04-1d42-4fb4-a5ab-9fa62f8d64c1",
+  "serviceName": "TestParentService",
+  "serviceVersion": "1.0",
+  "serviceUUID": "2f55da47-c58a-453e-909f-172c94765fba",
+  "serviceDescription": "TestParentService",
+  "serviceInvariantUUID": "13b817ae-6388-40cf-9261-1619b607f1de",
+  "resources": [
+    {
+      "resourceInstanceName": "TestVF 0",
+      "resourceName": "TestVF",
+      "resourceVersion": "1.0",
+      "resoucreType": "VF",
+      "resourceUUID": "5185253e-4bef-4eb4-bbf9-8c328c787ebd",
+      "resourceInvariantUUID": "ea8264db-3e24-4324-87cc-12c6903ed43d",
+      "resourceCustomizationUUID": "a959a3cb-4988-435c-9cb7-5a40ef2ef2ac",
+      "category": "Allotted Resource",
+      "subcategory": "Contrail Route",
+      "artifacts": [
+        {
+          "artifactName": "TestWF2-1_0.bpmn",
+          "artifactType": "WORKFLOW",
+          "artifactURL": "/sdc/v1/catalog/services/Testparentservice/1.0/resourceInstances/testvf0/artifacts/TestWF2-1_0.bpmn",
+          "artifactChecksum": "ZjUzNjg1NDMyMTc4MWJmZjFlNDcyOGQ0Zjc1YWQwYzQ\u003d",
+          "artifactDescription": "Workflow Artifact Description",
+          "artifactTimeout": 120,
+          "artifactUUID": "a90f8eaa-7c20-422f-8c81-aacbca6fb9e7",
+          "artifactVersion": "1"
+        },
+        {
+          "artifactName": "TestWF-1_0.bpmn",
+          "artifactType": "WORKFLOW",
+          "artifactURL": "/sdc/v1/catalog/services/Testparentservice/1.0/resourceInstances/testvf0/artifacts/TestWF-1_0.bpmn",
+          "artifactChecksum": "YzA4NDY3M2E3Njk3Y2FjMmViZjRlODIzNTY1NDY3MDY\u003d",
+          "artifactDescription": "Workflow Artifact Description",
+          "artifactTimeout": 120,
+          "artifactUUID": "f27066a1-c3a7-4672-b02e-1251b74b7b71",
+          "artifactVersion": "1"
+        },
+        {
+          "artifactName": "TestWF-2_0.bpmn",
+          "artifactType": "WORKFLOW",
+          "artifactURL": "/sdc/v1/catalog/services/Testparentservice/1.0/resourceInstances/testvf0/artifacts/TestWF-2_0.bpmn",
+          "artifactChecksum": "MTE0MDA2ZGNjZmY3YWEyNzNlNjUwZDQ2OGU4YTM5ZjU\u003d",
+          "artifactDescription": "Workflow Artifact Description",
+          "artifactTimeout": 120,
+          "artifactUUID": "f51d2203-d1f5-43f1-9492-e59d12facb8f",
+          "artifactVersion": "1"
+        }
+      ]
+    }
+  ],
+  "serviceArtifacts": [
+    {
+      "artifactName": "service-Testparentservice-template.yml",
+      "artifactType": "TOSCA_TEMPLATE",
+      "artifactURL": "/sdc/v1/catalog/services/Testparentservice/1.0/artifacts/service-Testparentservice-template.yml",
+      "artifactChecksum": "YWZlYWMwMjNkODBlYTI2MzZlNjg3YzEzODZiNzNkNTg\u003d",
+      "artifactDescription": "TOSCA representation of the asset",
+      "artifactTimeout": 0,
+      "artifactUUID": "8ec96c3f-d527-48bd-8dc5-1e7682bda676",
+      "artifactVersion": "1"
+    },
+    {
+      "artifactName": "service-Testparentservice-csar.csar",
+      "artifactType": "TOSCA_CSAR",
+      "artifactURL": "service-Testparentservice-csar.csar",
+      "artifactChecksum": "MTc4OWU0MGRhOTE4OGZiM2JiMjM3YmI3NzI2YWZjNjI\u003d",
+      "artifactDescription": "TOSCA definition package of the asset",
+      "artifactTimeout": 0,
+      "artifactUUID": "8dac522d-8e00-4794-819e-88e559ebc170",
+      "artifactVersion": "1"
+    }
+  ],
+  "workloadContext": "Production"
+}
\ No newline at end of file