Changed the task to capture the outputs on polling

Changed the task to capture the outputs on polling

Issue-ID: SO-3465
Signed-off-by: Benjamin, Max (mb388a) <mb388a@att.com>
Change-Id: I7ccbd90cd560e1616d2b7d59a4681874ddf8a351
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterImpl.java
index 9123ac9..b84d2a8 100644
--- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterImpl.java
+++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterImpl.java
@@ -31,6 +31,8 @@
 import java.util.Optional;
 import javax.jws.WebService;
 import javax.xml.ws.Holder;
+import org.apache.commons.lang3.mutable.MutableBoolean;
+import org.onap.logging.filter.base.ErrorCode;
 import org.onap.so.adapters.network.beans.ContrailPolicyRef;
 import org.onap.so.adapters.network.beans.ContrailPolicyRefSeq;
 import org.onap.so.adapters.network.beans.ContrailSubnet;
@@ -47,7 +49,6 @@
 import org.onap.so.db.catalog.data.repository.NetworkResourceRepository;
 import org.onap.so.db.catalog.utils.MavenLikeVersioning;
 import org.onap.so.entity.MsoRequest;
-import org.onap.logging.filter.base.ErrorCode;
 import org.onap.so.logger.LoggingAnchor;
 import org.onap.so.logger.MessageEnum;
 import org.onap.so.openstack.beans.HeatStatus;
@@ -150,7 +151,7 @@
         Holder<String> networkFqdn = new Holder<>();
         createNetwork(cloudSiteId, tenantId, networkType, modelCustomizationUuid, networkName, physicalNetworkName,
                 vlans, null, shared, external, failIfExists, backout, subnets, null, null, msoRequest, networkId,
-                neutronNetworkId, networkFqdn, subnetIdMap, rollback, true);
+                neutronNetworkId, networkFqdn, subnetIdMap, rollback, true, new MutableBoolean());
     }
 
     @Deprecated
@@ -164,7 +165,7 @@
             throws NetworkException {
         createNetwork(cloudSiteId, tenantId, networkType, modelCustomizationUuid, networkName, null, null, routeTargets,
                 shared, external, failIfExists, backout, subnets, policyFqdns, routeTableFqdns, msoRequest, networkId,
-                neutronNetworkId, networkFqdn, subnetIdMap, rollback, true);
+                neutronNetworkId, networkFqdn, subnetIdMap, rollback, true, new MutableBoolean());
     }
 
     /**
@@ -195,13 +196,14 @@
             String shared, String external, Boolean failIfExists, Boolean backout, List<Subnet> subnets,
             List<String> policyFqdns, List<String> routeTableFqdns, MsoRequest msoRequest, Holder<String> networkId,
             Holder<String> neutronNetworkId, Holder<String> networkFqdn, Holder<Map<String, String>> subnetIdMap,
-            Holder<NetworkRollback> rollback, Boolean pollForCompletion) throws NetworkException {
+            Holder<NetworkRollback> rollback, Boolean pollForCompletion, MutableBoolean isOs3Nw)
+            throws NetworkException {
         logger.debug("*** CREATE Network: {} of type {} in {}/{}", networkName, networkType, cloudSiteId, tenantId);
 
         // Will capture execution time for metrics
         long startTime = System.currentTimeMillis();
 
-        // Build a default rollback object (no actions performed)
+        // Build a default rollback object (no actions performed) //TODO remove
         NetworkRollback networkRollback = new NetworkRollback();
         networkRollback.setCloudId(cloudSiteId);
         networkRollback.setTenantId(tenantId);
@@ -241,13 +243,13 @@
         template = template.replaceAll("\r\n", "\n");
 
         boolean os3template = false;
-        String os3nw = OS3_NW;
 
-        os3nw = environment.getProperty(OS3_NW_PROPERTY, OS3_NW);
+        String os3nw = environment.getProperty(OS3_NW_PROPERTY, OS3_NW);
 
         if (template.contains(os3nw))
             os3template = true;
 
+        isOs3Nw.setValue(os3template);
         // First, look up to see if the Network already exists (by name).
         // For HEAT orchestration of networks, the stack name will always match the network name
         StackInfo heatStack = null;
@@ -280,20 +282,7 @@
                     }
                     Map<String, Object> outputs = heatStack.getOutputs();
 
-                    for (Map.Entry<String, Object> entry : outputs.entrySet()) {
-                        String key = entry.getKey();
-                        if (key != null && key.startsWith("subnet")) {
-                            if (os3template) // one subnet_id output
-                            {
-                                Map<String, String> map = getSubnetUUId(key, outputs, subnets);
-                                sMap.putAll(map);
-                            } else // multiples subnet_%aaid% outputs
-                            {
-                                String subnetUUId = (String) outputs.get(key);
-                                sMap.put(key.substring("subnet_id_".length()), subnetUUId);
-                            }
-                        }
-                    }
+                    sMap = buildSubnetMap(outputs, subnets, os3template);
                 }
                 subnetIdMap.value = sMap;
                 logger.warn("{} {} Found Existing network stack, status={} networkName={} for {}/{}",
@@ -390,20 +379,7 @@
         Map<String, Object> outputs = heatStack.getOutputs();
         Map<String, String> sMap = new HashMap<>();
         if (outputs != null) {
-            for (Map.Entry<String, Object> entry : outputs.entrySet()) {
-                String key = entry.getKey();
-                if (key != null && key.startsWith("subnet")) {
-                    if (os3template) // one subnet output expected
-                    {
-                        Map<String, String> map = getSubnetUUId(key, outputs, subnets);
-                        sMap.putAll(map);
-                    } else // multiples subnet_%aaid% outputs allowed
-                    {
-                        String subnetUUId = (String) outputs.get(key);
-                        sMap.put(key.substring("subnet_id_".length()), subnetUUId);
-                    }
-                }
-            }
+            sMap = buildSubnetMap(outputs, subnets, os3template);
             networkRollback.setNeutronNetworkId((String) outputs.get(NETWORK_ID));
         }
         subnetIdMap.value = sMap;
@@ -686,20 +662,7 @@
             Map<String, Object> outputs = heatStack.getOutputs();
             Map<String, String> sMap = new HashMap<>();
             if (outputs != null) {
-                for (Map.Entry<String, Object> entry : outputs.entrySet()) {
-                    String key = entry.getKey();
-                    if (key != null && key.startsWith("subnet")) {
-                        if (os3template) // one subnet output expected
-                        {
-                            Map<String, String> map = getSubnetUUId(key, outputs, subnets);
-                            sMap.putAll(map);
-                        } else // multiples subnet_%aaid% outputs allowed
-                        {
-                            String subnetUUId = (String) outputs.get(key);
-                            sMap.put(key.substring("subnet_id_".length()), subnetUUId);
-                        }
-                    }
-                }
+                sMap = buildSubnetMap(outputs, subnets, os3template);
             }
             subnetIdMap.value = sMap;
 
@@ -1361,7 +1324,8 @@
         return heatTemplate;
     }
 
-    private Map<String, String> getSubnetUUId(String key, Map<String, Object> outputs, List<Subnet> subnets) {
+    // TODO remove
+    public Map<String, String> getSubnetUUId(String key, Map<String, Object> outputs, List<Subnet> subnets) {
 
         Map<String, String> sMap = new HashMap<>();
 
@@ -1418,4 +1382,24 @@
         return updatedTemplate;
     }
 
+    public Map<String, String> buildSubnetMap(Map<String, Object> outputs, List<Subnet> subnets, boolean os3template) {
+
+        Map<String, String> sMap = new HashMap<>();
+        for (Map.Entry<String, Object> entry : outputs.entrySet()) {
+            String key = entry.getKey();
+            if (key != null && key.startsWith("subnet")) {
+                if (os3template) // one subnet_id output
+                {
+                    Map<String, String> map = getSubnetUUId(key, outputs, subnets);
+                    sMap.putAll(map);
+                } else // multiples subnet_%aaid% outputs
+                {
+                    String subnetUUId = (String) outputs.get(key);
+                    sMap.put(key.substring("subnet_id_".length()), subnetUUId);
+                }
+            }
+        }
+        return sMap;
+    }
+
 }
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/TaskServices.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/TaskServices.java
index 4e0c4ad..bd71474 100644
--- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/TaskServices.java
+++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/TaskServices.java
@@ -28,8 +28,6 @@
 import org.onap.so.adapters.tasks.orchestration.RollbackService;
 import org.onap.so.adapters.tasks.orchestration.StackService;
 import org.onap.so.utils.ExternalTaskServiceUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Profile;
 import org.springframework.stereotype.Component;
@@ -38,8 +36,6 @@
 @Profile("!test")
 public class TaskServices {
 
-    private static final Logger logger = LoggerFactory.getLogger(TaskServices.class);
-
     @Autowired
     private ExternalTaskServiceUtils externalTaskServiceUtils;
 
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/orchestration/PollService.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/orchestration/PollService.java
index ddbda5d..4f16674 100644
--- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/orchestration/PollService.java
+++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/orchestration/PollService.java
@@ -33,16 +33,31 @@
 import org.apache.commons.lang3.mutable.MutableBoolean;
 import org.camunda.bpm.client.task.ExternalTask;
 import org.camunda.bpm.client.task.ExternalTaskService;
+import org.onap.so.adapters.network.MsoNetworkAdapterImpl;
 import org.onap.so.adapters.nwrest.CreateNetworkRequest;
-import org.onap.so.adapters.vnfrest.CreateVfModuleRequest;
-import org.onap.so.adapters.vnfrest.CreateVolumeGroupRequest;
-import org.onap.so.adapters.vnfrest.DeleteVfModuleRequest;
-import org.onap.so.adapters.vnfrest.DeleteVolumeGroupRequest;
+import org.onap.so.adapters.nwrest.CreateNetworkResponse;
 import org.onap.so.adapters.nwrest.DeleteNetworkRequest;
+import org.onap.so.adapters.nwrest.DeleteNetworkResponse;
 import org.onap.so.adapters.nwrest.UpdateNetworkRequest;
+import org.onap.so.adapters.nwrest.UpdateNetworkResponse;
+import org.onap.so.adapters.vnf.MsoVnfAdapterImpl;
 import org.onap.so.adapters.vnf.VnfAdapterUtils;
+import org.onap.so.adapters.vnfrest.CreateVfModuleRequest;
+import org.onap.so.adapters.vnfrest.CreateVfModuleResponse;
+import org.onap.so.adapters.vnfrest.CreateVolumeGroupRequest;
+import org.onap.so.adapters.vnfrest.CreateVolumeGroupResponse;
+import org.onap.so.adapters.vnfrest.DeleteVfModuleRequest;
+import org.onap.so.adapters.vnfrest.DeleteVfModuleResponse;
+import org.onap.so.adapters.vnfrest.DeleteVolumeGroupRequest;
+import org.onap.so.adapters.vnfrest.DeleteVolumeGroupResponse;
+import org.onap.so.adapters.vnfrest.VfModuleRollback;
+import org.onap.so.adapters.vnfrest.VolumeGroupRollback;
 import org.onap.so.logging.tasks.AuditMDCSetup;
+import org.onap.so.openstack.beans.NetworkRollback;
+import org.onap.so.openstack.beans.StackInfo;
+import org.onap.so.openstack.beans.VnfRollback;
 import org.onap.so.openstack.exceptions.MsoException;
+import org.onap.so.openstack.mappers.StackInfoMapper;
 import org.onap.so.openstack.utils.MsoHeatUtils;
 import org.onap.so.utils.ExternalTaskUtils;
 import org.onap.so.utils.RetrySequenceLevel;
@@ -58,6 +73,12 @@
     private static final Logger logger = LoggerFactory.getLogger(PollService.class);
 
     @Autowired
+    private MsoVnfAdapterImpl vnfAdapterImpl;
+
+    @Autowired
+    private MsoNetworkAdapterImpl networkAdapterImpl;
+
+    @Autowired
     private MsoHeatUtils msoHeatUtils;
 
     @Autowired
@@ -76,45 +97,60 @@
         Map<String, Object> variables = new HashMap<>();
         MutableBoolean success = new MutableBoolean();
         String errorMessage = null;
+        String response = "";
         try {
             String xmlRequest = externalTask.getVariable("openstackAdapterTaskRequest");
             if (xmlRequest != null) {
                 Optional<String> requestType = findRequestType(xmlRequest);
                 if ("createVolumeGroupRequest".equals(requestType.get())) {
-                    determineCreateVolumeGroupStatus(xmlRequest, externalTask, success);
+                    response = determineCreateVolumeGroupStatus(xmlRequest, externalTask, success);
                 } else if ("createVfModuleRequest".equals(requestType.get())) {
-                    determineCreateVfModuleStatus(xmlRequest, externalTask, success);
+                    response = determineCreateVfModuleStatus(xmlRequest, externalTask, success);
                 } else if ("deleteVfModuleRequest".equals(requestType.get())) {
                     logger.debug("Executing External Task Poll Service for Delete Vf Module");
+                    String stackId = externalTask.getVariable("stackId");
                     DeleteVfModuleRequest req =
                             JAXB.unmarshal(new StringReader(xmlRequest), DeleteVfModuleRequest.class);
                     boolean isMulticloud = vnfAdapterUtils.isMulticloudMode(null, req.getCloudSiteId());
                     if (!isMulticloud) {
                         int timeoutMinutes = msoHeatUtils.getVfHeatTimeoutValue(req.getModelCustomizationUuid(), false);
-                        pollDeleteResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), externalTask,
-                                success);
-                    } else {
-                        success.setTrue();
+                        StackInfo stack = pollDeleteResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(),
+                                stackId, success);
+                        DeleteVfModuleResponse deleteResponse =
+                                new DeleteVfModuleResponse(req.getVnfId(), req.getVfModuleId(), Boolean.TRUE,
+                                        req.getMessageId(), vnfAdapterImpl.copyStringOutputs(stack.getOutputs()));
+                        response = deleteResponse.toXmlString();
                     }
                 } else if ("deleteVolumeGroupRequest".equals(requestType.get())) {
                     logger.debug("Executing External Task Poll Service for Delete Volume Group");
+                    String stackId = externalTask.getVariable("stackId");
                     DeleteVolumeGroupRequest req =
                             JAXB.unmarshal(new StringReader(xmlRequest), DeleteVolumeGroupRequest.class);
                     boolean isMulticloud = vnfAdapterUtils.isMulticloudMode(null, req.getCloudSiteId());
                     if (!isMulticloud) {
-                        pollDeleteResource(118, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
+                        pollDeleteResource(118, req.getCloudSiteId(), req.getTenantId(), stackId, success);
+                        DeleteVolumeGroupResponse deleteResponse =
+                                new DeleteVolumeGroupResponse(true, req.getMessageId());
+                        response = deleteResponse.toXmlString();
                     } else {
                         success.setTrue();
                     }
                 } else if ("createNetworkRequest".equals(requestType.get())) {
-                    determineCreateNetworkStatus(xmlRequest, externalTask, success);
+                    response = determineCreateNetworkStatus(xmlRequest, externalTask, success);
                 } else if ("deleteNetworkRequest".equals(requestType.get())) {
                     logger.debug("Executing External Task Poll Service for Delete Network");
+                    String stackId = externalTask.getVariable("stackId");
                     DeleteNetworkRequest req = JAXB.unmarshal(new StringReader(xmlRequest), DeleteNetworkRequest.class);
-                    pollDeleteResource(118, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
+                    pollDeleteResource(118, req.getCloudSiteId(), req.getTenantId(), stackId, success);
+                    DeleteNetworkResponse deleteResponse =
+                            new DeleteNetworkResponse(req.getNetworkId(), true, req.getMessageId());
+                    response = deleteResponse.toXmlString();
                 } else if ("updateNetworkRequest".equals(requestType.get())) {
                     UpdateNetworkRequest req = JAXB.unmarshal(new StringReader(xmlRequest), UpdateNetworkRequest.class);
                     pollUpdateResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
+                    UpdateNetworkResponse updateResponse =
+                            new UpdateNetworkResponse(req.getNetworkId(), null, null, req.getMessageId());
+                    response = updateResponse.toXmlString();
                 }
             }
         } catch (Exception e) {
@@ -123,6 +159,7 @@
             variables.put("openstackAdapterErrorMessage", errorMessage);
         }
 
+        variables.put("WorkflowResponse", response);
         variables.put("OpenstackPollSuccess", success.booleanValue());
         if (success.isTrue()) {
             externalTaskService.complete(externalTask, variables);
@@ -146,76 +183,119 @@
         }
     }
 
-    private void determineCreateVolumeGroupStatus(String xmlRequest, ExternalTask externalTask, MutableBoolean success)
-            throws MsoException {
+    private String determineCreateVolumeGroupStatus(String xmlRequest, ExternalTask externalTask,
+            MutableBoolean success) throws MsoException {
         CreateVolumeGroupRequest req = JAXB.unmarshal(new StringReader(xmlRequest), CreateVolumeGroupRequest.class);
         boolean isMulticloud = vnfAdapterUtils.isMulticloudMode(null, req.getCloudSiteId());
         if (!isMulticloud) {
             boolean pollRollbackStatus = externalTask.getVariable("PollRollbackStatus");
+            String stackId = externalTask.getVariable("stackId");
             if (pollRollbackStatus) {
                 logger.debug("Executing External Task Poll Service for Rollback Create Volume Group");
-                pollDeleteResource(118, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
+                pollDeleteResource(118, req.getCloudSiteId(), req.getTenantId(), stackId, success);
+                DeleteVolumeGroupResponse deleteResponse = new DeleteVolumeGroupResponse(true, req.getMessageId());
+                return deleteResponse.toXmlString();
             } else {
                 int timeoutMinutes = msoHeatUtils.getVfHeatTimeoutValue(req.getModelCustomizationUuid(), true);
-                pollCreateResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
+                StackInfo stack =
+                        pollCreateResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), stackId, success);
+                VolumeGroupRollback rb =
+                        new VolumeGroupRollback(req.getVolumeGroupId(), stackId, true, req.getTenantId(),
+                                req.getCloudOwner(), req.getCloudSiteId(), req.getMsoRequest(), req.getMessageId());
+                CreateVolumeGroupResponse createResponse = new CreateVolumeGroupResponse(req.getVolumeGroupId(),
+                        stackId, true, vnfAdapterImpl.copyStringOutputs(stack.getOutputs()), rb, req.getMessageId());
+                return createResponse.toXmlString();
             }
         } else {
             success.setTrue();
+            return null;
         }
     }
 
-    private void determineCreateVfModuleStatus(String xmlRequest, ExternalTask externalTask, MutableBoolean success)
+    private String determineCreateVfModuleStatus(String xmlRequest, ExternalTask externalTask, MutableBoolean success)
             throws MsoException {
         CreateVfModuleRequest req = JAXB.unmarshal(new StringReader(xmlRequest), CreateVfModuleRequest.class);
         boolean isMulticloud = vnfAdapterUtils.isMulticloudMode(null, req.getCloudSiteId());
+        String stackId = externalTask.getVariable("stackId");
         if (!isMulticloud) {
             boolean pollRollbackStatus = externalTask.getVariable("PollRollbackStatus");
             int timeoutMinutes = msoHeatUtils.getVfHeatTimeoutValue(req.getModelCustomizationUuid(), false);
             if (pollRollbackStatus) {
                 logger.debug("Executing External Task Poll Service for Rollback Create Vf Module");
-                pollDeleteResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
+                StackInfo stack =
+                        pollDeleteResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), stackId, success);
+                DeleteVfModuleResponse deleteResponse = new DeleteVfModuleResponse(req.getVnfId(), req.getVfModuleId(),
+                        Boolean.TRUE, req.getMessageId(), vnfAdapterImpl.copyStringOutputs(stack.getOutputs()));
+                return deleteResponse.toXmlString();
             } else {
                 logger.debug("Executing External Task Poll Service for Create Vf Module");
-                pollCreateResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
+                StackInfo stack =
+                        pollCreateResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), stackId, success);
+                VfModuleRollback modRollback = new VfModuleRollback(buildVnfRollback(req, stackId, isMulticloud),
+                        req.getVfModuleId(), stackId, req.getMessageId());
+                CreateVfModuleResponse createResponse =
+                        new CreateVfModuleResponse(req.getVnfId(), req.getVfModuleId(), stackId, Boolean.TRUE,
+                                vnfAdapterImpl.copyStringOutputs(stack.getOutputs()), modRollback, req.getMessageId());
+                return createResponse.toXmlString();
             }
         } else {
             success.setTrue();
+            return null;
         }
     }
 
-    private void determineCreateNetworkStatus(String xmlRequest, ExternalTask externalTask, MutableBoolean success)
+    private String determineCreateNetworkStatus(String xmlRequest, ExternalTask externalTask, MutableBoolean success)
             throws MsoException {
         CreateNetworkRequest req = JAXB.unmarshal(new StringReader(xmlRequest), CreateNetworkRequest.class);
+        String stackId = externalTask.getVariable("stackId");
         boolean pollRollbackStatus = externalTask.getVariable("PollRollbackStatus");
         int timeoutMinutes =
                 msoHeatUtils.getNetworkHeatTimeoutValue(req.getModelCustomizationUuid(), req.getNetworkType());
         if (pollRollbackStatus) {
             logger.debug("Executing External Task Poll Service for Rollback Create Network");
-            pollDeleteResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
+            pollDeleteResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), stackId, success);
+            DeleteNetworkResponse response = new DeleteNetworkResponse(req.getNetworkId(), true, req.getMessageId());
+            return response.toXmlString();
         } else {
             logger.debug("Executing External Task Poll Service for Create Network");
-            pollCreateResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
+            boolean os3Nw = externalTask.getVariable("os3Nw");
+            StackInfo stack =
+                    pollCreateResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), stackId, success);
+            String networkFqdn = "";
+            String neutronNetworkId = "";
+            Map<String, String> subnetMap = new HashMap<>();
+            if (stack.getOutputs() != null) {
+                networkFqdn = (String) stack.getOutputs().get("network_fqdn");
+                neutronNetworkId = (String) stack.getOutputs().get("network_id");
+                subnetMap = networkAdapterImpl.buildSubnetMap(stack.getOutputs(), req.getSubnets(), os3Nw);
+            }
+            CreateNetworkResponse response = new CreateNetworkResponse(req.getNetworkId(), neutronNetworkId, stackId,
+                    networkFqdn, true, subnetMap, buildNetworkRollback(req, stackId), req.getMessageId());
+            return response.toXmlString();
+
         }
     }
 
-    private void pollCreateResource(int pollingTimeout, String cloudSiteId, String tenantId, ExternalTask externalTask,
+    private StackInfo pollCreateResource(int pollingTimeout, String cloudSiteId, String tenantId, String stackId,
             MutableBoolean success) throws MsoException {
-        Stack currentStack = createCurrentStack(externalTask.getVariable("stackId"));
+        Stack currentStack = createCurrentStack(stackId);
         Stack stack = msoHeatUtils.pollStackForStatus(pollingTimeout, currentStack, "CREATE_IN_PROGRESS", cloudSiteId,
                 tenantId, false);
         msoHeatUtils.postProcessStackCreate(stack, false, 0, false, cloudSiteId, tenantId, null);
         success.setTrue();
+        return new StackInfoMapper(stack).map();
     }
 
-    private void pollDeleteResource(int pollingTimeout, String cloudSiteId, String tenantId, ExternalTask externalTask,
+    private StackInfo pollDeleteResource(int pollingTimeout, String cloudSiteId, String tenantId, String stackId,
             MutableBoolean success) throws MsoException {
-        Stack currentStack = createCurrentStack(externalTask.getVariable("stackId"));
+        Stack currentStack = createCurrentStack(stackId);
         Stack stack = msoHeatUtils.pollStackForStatus(pollingTimeout, currentStack, "DELETE_IN_PROGRESS", cloudSiteId,
                 tenantId, true);
         if (stack != null) { // if stack is null it was not found and no need to do post process
             msoHeatUtils.postProcessStackDelete(stack);
         }
         success.setTrue();
+        return new StackInfoMapper(stack).map();
     }
 
     private void pollUpdateResource(String cloudSiteId, String tenantId, ExternalTask externalTask,
@@ -251,4 +331,36 @@
         currentStack.setStackName(stackName);
         return currentStack;
     }
+
+    private VnfRollback buildVnfRollback(CreateVfModuleRequest req, String stackId, boolean isMulticloud) {
+        VnfRollback vfRollback = new VnfRollback();
+        vfRollback.setCloudSiteId(req.getCloudSiteId());
+        vfRollback.setCloudOwner(req.getCloudOwner());
+        vfRollback.setTenantId(req.getTenantId());
+        vfRollback.setMsoRequest(req.getMsoRequest());
+        vfRollback.setRequestType(req.getRequestType());
+        vfRollback.setVolumeGroupHeatStackId(req.getVolumeGroupStackId());
+        vfRollback.setBaseGroupHeatStackId(req.getBaseVfModuleStackId());
+        vfRollback.setIsBase(false);
+        vfRollback.setModelCustomizationUuid(req.getModelCustomizationUuid());
+        vfRollback.setVnfId(stackId);
+        vfRollback.setVnfCreated(true);
+        if (isMulticloud) {
+            vfRollback.setMode("CFY");
+        }
+        return vfRollback;
+    }
+
+    private NetworkRollback buildNetworkRollback(CreateNetworkRequest req, String stackId) {
+        NetworkRollback networkRollback = new NetworkRollback();
+        networkRollback.setCloudId(req.getCloudSiteId());
+        networkRollback.setTenantId(req.getTenantId());
+        networkRollback.setMsoRequest(req.getMsoRequest());
+        networkRollback.setModelCustomizationUuid(req.getModelCustomizationUuid());
+        networkRollback.setNetworkStackId(stackId);
+        networkRollback.setNetworkCreated(true);
+        networkRollback.setNetworkType(req.getNetworkType());
+
+        return networkRollback;
+    }
 }
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/orchestration/StackService.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/orchestration/StackService.java
index 7be1620..6b76c3a 100644
--- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/orchestration/StackService.java
+++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/orchestration/StackService.java
@@ -39,12 +39,9 @@
 import org.onap.so.adapters.network.exceptions.NetworkException;
 import org.onap.so.adapters.nwrest.ContrailNetwork;
 import org.onap.so.adapters.nwrest.CreateNetworkRequest;
-import org.onap.so.adapters.nwrest.CreateNetworkResponse;
 import org.onap.so.adapters.nwrest.DeleteNetworkRequest;
-import org.onap.so.adapters.nwrest.DeleteNetworkResponse;
 import org.onap.so.adapters.nwrest.ProviderVlanNetwork;
 import org.onap.so.adapters.nwrest.RollbackNetworkRequest;
-import org.onap.so.adapters.nwrest.RollbackNetworkResponse;
 import org.onap.so.adapters.nwrest.UpdateNetworkRequest;
 import org.onap.so.adapters.nwrest.UpdateNetworkResponse;
 import org.onap.so.adapters.vnf.MsoVnfAdapterImpl;
@@ -52,15 +49,9 @@
 import org.onap.so.adapters.vnf.VnfAdapterUtils;
 import org.onap.so.adapters.vnf.exceptions.VnfException;
 import org.onap.so.adapters.vnfrest.CreateVfModuleRequest;
-import org.onap.so.adapters.vnfrest.CreateVfModuleResponse;
 import org.onap.so.adapters.vnfrest.CreateVolumeGroupRequest;
-import org.onap.so.adapters.vnfrest.CreateVolumeGroupResponse;
 import org.onap.so.adapters.vnfrest.DeleteVfModuleRequest;
-import org.onap.so.adapters.vnfrest.DeleteVfModuleResponse;
 import org.onap.so.adapters.vnfrest.DeleteVolumeGroupRequest;
-import org.onap.so.adapters.vnfrest.DeleteVolumeGroupResponse;
-import org.onap.so.adapters.vnfrest.VfModuleRollback;
-import org.onap.so.adapters.vnfrest.VolumeGroupRollback;
 import org.onap.so.logging.tasks.AuditMDCSetup;
 import org.onap.so.openstack.beans.NetworkRollback;
 import org.onap.so.openstack.beans.RouteTarget;
@@ -94,7 +85,6 @@
     private static final String SHARED = "shared";
     private static final String EXTERNAL = "external";
 
-    // TODO set backout earlier in case of exception??
     public void executeExternalTask(ExternalTask externalTask, ExternalTaskService externalTaskService) {
         Map<String, Object> variables = new HashMap<>();
         mdcSetup.setupMDC(externalTask);
@@ -102,7 +92,7 @@
         logger.debug("Starting External Task Stack Service. {}", xmlRequest);
         MutableBoolean success = new MutableBoolean();
         MutableBoolean backout = new MutableBoolean();
-        String response = "";
+        MutableBoolean os3Nw = new MutableBoolean();
         Holder<String> canonicalStackId = new Holder<>();
         String errorMessage = "";
         try {
@@ -117,26 +107,26 @@
                 Holder<NetworkRollback> networkRollback = new Holder<>();
                 if ("createVolumeGroupRequest".equals(requestType.get())) {
                     logger.debug("Executing External Task Stack Service For Create Volume Group");
-                    response = createVolumeGroup(xmlRequest, outputs, vnfRollback, canonicalStackId, backout, success);
+                    createVolumeGroup(xmlRequest, outputs, vnfRollback, canonicalStackId, backout, success);
                 } else if ("createVfModuleRequest".equals(requestType.get())) {
                     logger.debug("Executing External Task Stack Service For Create Vf Module");
-                    response = createVfModule(xmlRequest, outputs, vnfRollback, canonicalStackId, backout, success);
+                    createVfModule(xmlRequest, outputs, vnfRollback, canonicalStackId, backout, success);
                 } else if ("deleteVfModuleRequest".equals(requestType.get())) {
                     logger.debug("Executing External Task Stack Service For Delete Vf Module");
-                    response = deleteVfModule(xmlRequest, outputs, vnfRollback, canonicalStackId, backout, success);
+                    deleteVfModule(xmlRequest, outputs, vnfRollback, canonicalStackId, backout, success);
                 } else if ("deleteVolumeGroupRequest".equals(requestType.get())) {
                     logger.debug("Executing External Task Stack Service For Delete Volume Group");
-                    response = deleteVolumeGroup(xmlRequest, outputs, vnfRollback, canonicalStackId, backout, success);
+                    deleteVolumeGroup(xmlRequest, outputs, vnfRollback, canonicalStackId, backout, success);
                 } else if ("createNetworkRequest".equals(requestType.get())) {
-                    response = createNetwork(xmlRequest, networkId, neutronNetworkId, networkFqdn, subnetIdMap,
-                            networkRollback, canonicalStackId, backout, success);
+                    createNetwork(xmlRequest, networkId, neutronNetworkId, networkFqdn, subnetIdMap, networkRollback,
+                            canonicalStackId, backout, success, os3Nw);
                 } else if ("deleteNetworkRequest".equals(requestType.get())) {
-                    response = deleteNetwork(xmlRequest, canonicalStackId, backout, success);
+                    deleteNetwork(xmlRequest, canonicalStackId, backout, success);
                 } else if ("updateNetworkRequest".equals(requestType.get())) {
-                    response =
-                            updateNetwork(xmlRequest, subnetIdMap, networkRollback, canonicalStackId, backout, success);
+
+                    updateNetwork(xmlRequest, subnetIdMap, networkRollback, canonicalStackId, backout, success);
                 } else if ("rollbackNetworkRequest".equals(requestType.get())) {
-                    response = rollbackNetwork(xmlRequest, canonicalStackId, backout, success);
+                    rollbackNetwork(xmlRequest, canonicalStackId, backout, success);
                 }
             }
         } catch (Exception e) {
@@ -144,7 +134,6 @@
             errorMessage = e.getMessage();
         }
         variables.put("backout", backout.booleanValue());
-        variables.put("WorkflowResponse", response);
         variables.put("OpenstackInvokeSuccess", success.booleanValue());
         variables.put("stackId", canonicalStackId.value);
         variables.put("openstackAdapterErrorMessage", errorMessage);
@@ -152,6 +141,7 @@
         variables.put("rollbackPerformed", false);
         variables.put("OpenstackRollbackSuccess", false);
         variables.put("OpenstackPollSuccess", false);
+        variables.put("os3Nw", os3Nw.booleanValue());
 
         if (success.isTrue()) {
             externalTaskService.complete(externalTask, variables);
@@ -162,10 +152,9 @@
         }
     }
 
-    private String createVolumeGroup(String xmlRequest, Holder<Map<String, String>> outputs,
+    private void createVolumeGroup(String xmlRequest, Holder<Map<String, String>> outputs,
             Holder<VnfRollback> vnfRollback, Holder<String> canonicalStackId, MutableBoolean backout,
             MutableBoolean success) throws VnfException {
-        Holder<String> stackId = new Holder<>();
         CreateVolumeGroupRequest req = JAXB.unmarshal(new StringReader(xmlRequest), CreateVolumeGroupRequest.class);
         String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
         boolean isMulticloud = vnfAdapterUtils.isMulticloudMode(null, req.getCloudSiteId());
@@ -173,28 +162,19 @@
             vnfPluginImpl.createVfModule(req.getCloudSiteId(), req.getCloudOwner(), req.getTenantId(),
                     completeVnfVfModuleType, req.getVnfVersion(), "", req.getVolumeGroupName(), "", "VOLUME", null,
                     null, req.getModelCustomizationUuid(), req.getVolumeGroupParams(), false, true,
-                    req.getEnableBridge(), req.getMsoRequest(), stackId, outputs, vnfRollback);
+                    req.getEnableBridge(), req.getMsoRequest(), canonicalStackId, outputs, vnfRollback);
         } else {
             vnfAdapterImpl.createVfModule(req.getCloudSiteId(), req.getCloudOwner(), req.getTenantId(),
                     completeVnfVfModuleType, req.getVnfVersion(), "", req.getVolumeGroupName(), "", "VOLUME", null,
                     null, req.getModelCustomizationUuid(), req.getVolumeGroupParams(), false, true,
-                    req.getEnableBridge(), req.getMsoRequest(), stackId, outputs, vnfRollback);
+                    req.getEnableBridge(), req.getMsoRequest(), canonicalStackId, outputs, vnfRollback);
         }
         success.setTrue();
         backout.setValue(!req.getSuppressBackout());
-        VolumeGroupRollback rb = new VolumeGroupRollback(req.getVolumeGroupId(), stackId.value,
-                vnfRollback.value.getVnfCreated(), req.getTenantId(), req.getCloudOwner(), req.getCloudSiteId(),
-                req.getMsoRequest(), req.getMessageId());
-        canonicalStackId.value = stackId.value;
-        CreateVolumeGroupResponse createResponse = new CreateVolumeGroupResponse(req.getVolumeGroupId(), stackId.value,
-                vnfRollback.value.getVnfCreated(), outputs.value, rb, req.getMessageId());
-        return createResponse.toXmlString();
     }
 
-    private String createVfModule(String xmlRequest, Holder<Map<String, String>> outputs,
-            Holder<VnfRollback> vnfRollback, Holder<String> canonicalStackId, MutableBoolean backout,
-            MutableBoolean success) throws VnfException {
-        Holder<String> stackId = new Holder<>();
+    private void createVfModule(String xmlRequest, Holder<Map<String, String>> outputs, Holder<VnfRollback> vnfRollback,
+            Holder<String> canonicalStackId, MutableBoolean backout, MutableBoolean success) throws VnfException {
         CreateVfModuleRequest req = JAXB.unmarshal(new StringReader(xmlRequest), CreateVfModuleRequest.class);
         String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
         boolean isMulticloud = vnfAdapterUtils.isMulticloudMode(null, req.getCloudSiteId());
@@ -203,27 +183,20 @@
                     completeVnfVfModuleType, req.getVnfVersion(), req.getVnfId(), req.getVfModuleName(),
                     req.getVfModuleId(), req.getRequestType(), req.getVolumeGroupStackId(),
                     req.getBaseVfModuleStackId(), req.getModelCustomizationUuid(), req.getVfModuleParams(), false,
-                    false, req.getEnableBridge(), req.getMsoRequest(), stackId, outputs, vnfRollback);
+                    false, req.getEnableBridge(), req.getMsoRequest(), canonicalStackId, outputs, vnfRollback);
         } else {
             vnfAdapterImpl.createVfModule(req.getCloudSiteId(), req.getCloudOwner(), req.getTenantId(),
                     completeVnfVfModuleType, req.getVnfVersion(), req.getVnfId(), req.getVfModuleName(),
                     req.getVfModuleId(), req.getRequestType(), req.getVolumeGroupStackId(),
                     req.getBaseVfModuleStackId(), req.getModelCustomizationUuid(), req.getVfModuleParams(), false,
-                    false, req.getEnableBridge(), req.getMsoRequest(), stackId, outputs, vnfRollback);
+                    false, req.getEnableBridge(), req.getMsoRequest(), canonicalStackId, outputs, vnfRollback);
         }
         success.setTrue();
         backout.setValue(req.getBackout());
-        canonicalStackId.value = stackId.value;
-        VfModuleRollback modRollback =
-                new VfModuleRollback(vnfRollback.value, req.getVfModuleId(), stackId.value, req.getMessageId());
-        CreateVfModuleResponse createResponse = new CreateVfModuleResponse(req.getVnfId(), req.getVfModuleId(),
-                stackId.value, Boolean.TRUE, outputs.value, modRollback, req.getMessageId());
-        return createResponse.toXmlString();
     }
 
-    private String deleteVfModule(String xmlRequest, Holder<Map<String, String>> outputs,
-            Holder<VnfRollback> vnfRollback, Holder<String> canonicalStackId, MutableBoolean backout,
-            MutableBoolean success) throws VnfException {
+    private void deleteVfModule(String xmlRequest, Holder<Map<String, String>> outputs, Holder<VnfRollback> vnfRollback,
+            Holder<String> canonicalStackId, MutableBoolean backout, MutableBoolean success) throws VnfException {
         backout.setFalse();
         DeleteVfModuleRequest req = JAXB.unmarshal(new StringReader(xmlRequest), DeleteVfModuleRequest.class);
         boolean isMulticloud = vnfAdapterUtils.isMulticloudMode(null, req.getCloudSiteId());
@@ -241,12 +214,9 @@
         } else {
             canonicalStackId.value = req.getVfModuleStackId();
         }
-        DeleteVfModuleResponse deleteResponse = new DeleteVfModuleResponse(req.getVnfId(), req.getVfModuleId(),
-                Boolean.TRUE, req.getMessageId(), outputs.value);
-        return deleteResponse.toXmlString();
     }
 
-    private String deleteVolumeGroup(String xmlRequest, Holder<Map<String, String>> outputs,
+    private void deleteVolumeGroup(String xmlRequest, Holder<Map<String, String>> outputs,
             Holder<VnfRollback> vnfRollback, Holder<String> canonicalStackId, MutableBoolean backout,
             MutableBoolean success) throws VnfException {
         backout.setFalse();
@@ -255,14 +225,12 @@
                 req.getVolumeGroupStackId(), req.getMsoRequest(), false);
         success.setTrue();
         canonicalStackId.value = req.getVolumeGroupStackId();
-        DeleteVolumeGroupResponse deleteResponse = new DeleteVolumeGroupResponse(true, req.getMessageId());
-        return deleteResponse.toXmlString();
     }
 
-    private String createNetwork(String xmlRequest, Holder<String> networkId, Holder<String> neutronNetworkId,
+    private void createNetwork(String xmlRequest, Holder<String> networkId, Holder<String> neutronNetworkId,
             Holder<String> networkFqdn, Holder<Map<String, String>> subnetIdMap,
             Holder<NetworkRollback> networkRollback, Holder<String> canonicalStackId, MutableBoolean backout,
-            MutableBoolean success) throws NetworkException {
+            MutableBoolean success, MutableBoolean os3) throws NetworkException {
         CreateNetworkRequest req = JAXB.unmarshal(new StringReader(xmlRequest), CreateNetworkRequest.class);
         HashMap<String, String> params = (HashMap<String, String>) req.getNetworkParams();
         if (params == null) {
@@ -306,18 +274,13 @@
         networkAdapterImpl.createNetwork(req.getCloudSiteId(), req.getTenantId(), req.getNetworkType(),
                 req.getModelCustomizationUuid(), req.getNetworkName(), physicalNetworkName, vlans, routeTargets, shared,
                 external, req.getFailIfExists(), false, req.getSubnets(), fqdns, routeTable, req.getMsoRequest(),
-                networkId, neutronNetworkId, networkFqdn, subnetIdMap, networkRollback, true);
+                networkId, neutronNetworkId, networkFqdn, subnetIdMap, networkRollback, true, os3);
         success.setTrue();
         backout.setValue(req.getBackout());
         canonicalStackId.value = networkRollback.value.getNetworkStackId();
-
-        CreateNetworkResponse response = new CreateNetworkResponse(req.getNetworkId(), neutronNetworkId.value,
-                networkRollback.value.getNetworkStackId(), networkFqdn.value, networkRollback.value.getNetworkCreated(),
-                subnetIdMap.value, networkRollback.value, req.getMessageId());
-        return response.toXmlString();
     }
 
-    private String deleteNetwork(String xmlRequest, Holder<String> canonicalStackId, MutableBoolean backout,
+    private void deleteNetwork(String xmlRequest, Holder<String> canonicalStackId, MutableBoolean backout,
             MutableBoolean success) throws NetworkException {
         backout.setFalse();
         DeleteNetworkRequest req = JAXB.unmarshal(new StringReader(xmlRequest), DeleteNetworkRequest.class);
@@ -328,13 +291,9 @@
 
         canonicalStackId.value = req.getNetworkStackId();
         success.setTrue();
-
-        DeleteNetworkResponse response =
-                new DeleteNetworkResponse(req.getNetworkId(), networkDeleted.value, req.getMessageId());
-        return response.toXmlString();
     }
 
-    private String rollbackNetwork(String xmlRequest, Holder<String> canonicalStackId, MutableBoolean backout,
+    private void rollbackNetwork(String xmlRequest, Holder<String> canonicalStackId, MutableBoolean backout,
             MutableBoolean success) throws NetworkException {
         backout.setFalse();
         RollbackNetworkRequest req = JAXB.unmarshal(new StringReader(xmlRequest), RollbackNetworkRequest.class);
@@ -344,9 +303,6 @@
 
         canonicalStackId.value = rollback.getNetworkStackId();
         success.setTrue();
-
-        RollbackNetworkResponse response = new RollbackNetworkResponse(true, req.getMessageId());
-        return response.toXmlString();
     }
 
     private String updateNetwork(String xmlRequest, Holder<Map<String, String>> subnetIdMap,
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfAdapterImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfAdapterImpl.java
index 7acf953..4ee6cf2 100644
--- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfAdapterImpl.java
+++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfAdapterImpl.java
@@ -318,7 +318,7 @@
         return;
     }
 
-    private Map<String, String> copyStringOutputs(Map<String, Object> stackOutputs) {
+    public Map<String, String> copyStringOutputs(Map<String, Object> stackOutputs) {
         Map<String, String> stringOutputs = new HashMap<>();
         for (Map.Entry<String, Object> entry : stackOutputs.entrySet()) {
             String key = entry.getKey();
@@ -408,6 +408,7 @@
         return stringMap;
     }
 
+    // TODO remove rollback and outputs and polling
     public void createVfModule(String cloudSiteId, String cloudOwner, String tenantId, String vnfType,
             String vnfVersion, String genericVnfName, String vnfName, String vfModuleId, String requestType,
             String volumeGroupHeatStackId, String baseVfHeatStackId, String modelCustomizationUuid,
@@ -464,6 +465,7 @@
         logger.debug("requestTypeString = " + requestTypeString + ", nestedStackId = " + nestedStackId
                 + ", nestedBaseStackId = " + nestedBaseStackId);
 
+        // TODO remove
         // Build a default rollback object (no actions performed)
         VnfRollback vfRollback = new VnfRollback();
         vfRollback.setCloudSiteId(cloudSiteId);
@@ -963,7 +965,7 @@
 
             vnfId.value = heatStack.getCanonicalName();
             outputs.value = copyStringOutputs(heatStack.getOutputs());
-            rollback.value = vfRollback;
+            rollback.value = vfRollback; // TODO remove
             logger.debug("VF Module {} successfully created", vfModuleName);
         } catch (Exception e) {
             logger.debug("unhandled exception in create VF", e);
diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/tasks/orchestration/StackServiceTest.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/tasks/orchestration/StackServiceTest.java
index afe7e17..7a00cfe 100644
--- a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/tasks/orchestration/StackServiceTest.java
+++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/tasks/orchestration/StackServiceTest.java
@@ -89,14 +89,15 @@
 
         Map<String, Object> variables = new HashMap<>();
         variables.put("backout", true);
-        variables.put("WorkflowResponse", "");
         variables.put("OpenstackInvokeSuccess", true);
         variables.put("stackId", null);
-        variables.put("openstackAdapterErrorMessage", null);
+        variables.put("openstackAdapterErrorMessage", "");
         variables.put("PollRollbackStatus", false);
         variables.put("rollbackPerformed", false);
         variables.put("OpenstackRollbackSuccess", false);
         variables.put("OpenstackPollSuccess", false);
+        variables.put("os3Nw", false);
+
 
         Mockito.verify(vnfAdapterImpl, Mockito.times(1)).createVfModule(Mockito.eq("regionOne"),
                 Mockito.eq("CloudOwner"), Mockito.eq("0422ffb57ba042c0800a29dc85ca70f8"),