fix keypair conflict issue in openstack adapter 81/88181/3
authorSmokowski, Steven <steve.smokowski@att.com>
Tue, 21 May 2019 15:58:01 +0000 (11:58 -0400)
committerBenjamin, Max (mb388a) <mb388a@us.att.com>
Fri, 31 May 2019 14:42:51 +0000 (10:42 -0400)
Fix wiremock stubs to return proper data and url
Fix copyright header issue on unit test file
Fix keypair issue, clean up unit tests and logging
Fix issues found in unit testing, update data
Fix broken Unit tests that used invalid data
Continue Refactor to support keypair failure scenario
Update logic for when to auto delete a stuck keypair

Change-Id: Ice5256cf0381a3b46d1c442907c0f321a1c0d006
Issue-ID: SO-1897
Signed-off-by: Benjamin, Max (mb388a) <mb388a@us.att.com>
24 files changed:
adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoCommonUtils.java
adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java
adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtilsWithUpdate.java
adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoKeystoneUtils.java
adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/NovaClientImpl.java
adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/StackCreationException.java [new file with mode: 0644]
adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/StackResultWrapper.java [new file with mode: 0644]
adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/StackRollbackException.java [new file with mode: 0644]
adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/StackStatusHandler.java
adapters/mso-adapter-utils/src/test/java/org/onap/so/openstack/utils/MsoHeatUtilsITTest.java [new file with mode: 0644]
adapters/mso-adapter-utils/src/test/java/org/onap/so/openstack/utils/MsoHeatUtilsTest.java
adapters/mso-adapter-utils/src/test/java/org/onap/so/openstack/utils/MsoHeatUtilsWithUpdateTest.java
adapters/mso-adapter-utils/src/test/resources/__files/OpenstackResponse_Stack_Created.json
adapters/mso-adapters-rest-interface/src/main/java/org/onap/so/openstack/beans/HostRoute.java
adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackService.java
adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfAdapterImpl.java
adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/network/MSONetworkAdapterImplTest.java
adapters/mso-openstack-adapters/src/test/resources/CreateNetwork.xml
adapters/mso-openstack-adapters/src/test/resources/__files/OpenstackResponse_Stack.json
adapters/mso-openstack-adapters/src/test/resources/__files/OpenstackResponse_Stack_Created_VfModule.json
adapters/mso-openstack-adapters/src/test/resources/__files/OpenstackResponse_Stack_DeleteComplete.json
adapters/mso-openstack-adapters/src/test/resources/__files/OpenstackResponse_VnfBaseStackId.json
adapters/mso-openstack-adapters/src/test/resources/logback-test.xml
vnfm-simulator/vnfm-service/pom.xml

index a6a2f84..4ea205a 100644 (file)
@@ -127,8 +127,8 @@ public class MsoCommonUtils {
                                 retryCount--;
                                 retry = true;
                                 logger.debug(
-                                        "OpenStackResponseException ResponseCode: {} request:{} Retry indicated. Attempts remaining:{}",
-                                        code, requestType, retryCount);
+                                        "OpenStackResponseException ResponseCode: {} Retry indicated. Attempts remaining:{}",
+                                        code, retryCount);
                                 break;
                             }
                         } catch (NumberFormatException e1) {
@@ -152,7 +152,7 @@ public class MsoCommonUtils {
                 // Connection to Openstack failed
                 if (retryCount > 0) {
                     retryCount--;
-                    logger.debug(" request: {} Retry indicated. Attempts remaining:{}", requestType, retryCount);
+                    logger.debug("Retry indicated. Attempts remaining:{}", retryCount);
                     try {
                         Thread.sleep(retryDelay * 1000L);
                     } catch (InterruptedException e1) {
@@ -223,40 +223,29 @@ public class MsoCommonUtils {
             try {
                 // Failed Heat calls return an Explanation entity body.
                 Explanation explanation = re.getResponse().getErrorEntity(Explanation.class);
-                logger.error("{} {} Exception - Openstack Error on {} : {}", MessageEnum.RA_CONNECTION_EXCEPTION,
-                        ErrorCode.DataError.getValue(), context, explanation.toString());
+                logger.error("Exception - Openstack Error on {} : {}", context, explanation);
                 String fullError = explanation.getExplanation() + ", error.type=" + explanation.getError().getType()
                         + ", error.message=" + explanation.getError().getMessage();
-                logger.debug(fullError);
-                me = new MsoOpenstackException(explanation.getCode(), explanation.getTitle(),
-                        // explanation.getExplanation ());
-                        fullError);
+                logger.error(fullError);
+                me = new MsoOpenstackException(explanation.getCode(), explanation.getTitle(), fullError);
             } catch (Exception e2) {
                 // Couldn't parse the body as an "Explanation". Report the original HTTP error.
                 logger.error("{} {} Exception - HTTP Error on {}: {}, ", MessageEnum.RA_CONNECTION_EXCEPTION,
                         ErrorCode.DataError.getValue(), context, re.getStatus(), e.getMessage(), e2);
-                me = new MsoOpenstackException(re.getStatus(), re.getMessage(), "");
+                me = new MsoOpenstackException(re.getStatus(), re.getMessage(), re.getMessage());
             }
 
             // Add the context of the error
             me.addContext(context);
 
-            // Generate an alarm for 5XX and higher errors.
-            if (re.getStatus() >= 500) {
-
-            }
         } else if (e instanceof OpenStackConnectException) {
             OpenStackConnectException ce = (OpenStackConnectException) e;
-
             me = new MsoIOException(ce.getMessage());
             me.addContext(context);
-
             // Generate an alarm for all connection errors.
-
             logger.error("{} {} Openstack Heat connection error on {}: ", MessageEnum.RA_CONNECTION_EXCEPTION,
                     ErrorCode.DataError.getValue(), context, e);
         }
-
         return me;
     }
 
@@ -435,7 +424,7 @@ public class MsoCommonUtils {
 
 
     /**
-     * Gets the Nova client
+     * Gets the Keystone Authorization
      *
      * @param cloudSite the cloud site
      * @param tenantId the tenant id
index 376ed20..683bb28 100644 (file)
@@ -31,6 +31,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 import org.onap.logging.ref.slf4j.ONAPLogConstants;
 import org.onap.so.adapters.vdu.CloudInfo;
 import org.onap.so.adapters.vdu.PluginAction;
@@ -43,15 +45,11 @@ import org.onap.so.adapters.vdu.VduPlugin;
 import org.onap.so.adapters.vdu.VduStateType;
 import org.onap.so.adapters.vdu.VduStatus;
 import org.onap.so.cloud.CloudConfig;
-import org.onap.so.cloud.authentication.AuthenticationMethodFactory;
 import org.onap.so.cloud.authentication.KeystoneAuthHolder;
-import org.onap.so.cloud.authentication.KeystoneV3Authentication;
-import org.onap.so.cloud.authentication.ServiceEndpointNotFoundException;
 import org.onap.so.db.catalog.beans.CloudIdentity;
 import org.onap.so.db.catalog.beans.CloudSite;
 import org.onap.so.db.catalog.beans.HeatTemplate;
 import org.onap.so.db.catalog.beans.HeatTemplateParam;
-import org.onap.so.db.catalog.beans.ServerType;
 import org.onap.so.db.request.beans.CloudApiRequests;
 import org.onap.so.db.request.beans.InfraActiveRequests;
 import org.onap.so.db.request.client.RequestsDbClient;
@@ -59,15 +57,12 @@ import org.onap.so.logger.ErrorCode;
 import org.onap.so.logger.MessageEnum;
 import org.onap.so.openstack.beans.HeatStatus;
 import org.onap.so.openstack.beans.StackInfo;
-import org.onap.so.openstack.exceptions.MsoAdapterException;
 import org.onap.so.openstack.exceptions.MsoCloudSiteNotFound;
 import org.onap.so.openstack.exceptions.MsoException;
-import org.onap.so.openstack.exceptions.MsoIOException;
 import org.onap.so.openstack.exceptions.MsoOpenstackException;
 import org.onap.so.openstack.exceptions.MsoStackAlreadyExists;
 import org.onap.so.openstack.exceptions.MsoTenantNotFound;
 import org.onap.so.openstack.mappers.StackInfoMapper;
-import org.onap.so.utils.CryptoUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.MDC;
@@ -77,28 +72,31 @@ import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Component;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.Strings;
 import com.woorea.openstack.base.client.OpenStackConnectException;
 import com.woorea.openstack.base.client.OpenStackRequest;
 import com.woorea.openstack.base.client.OpenStackResponseException;
 import com.woorea.openstack.heat.Heat;
 import com.woorea.openstack.heat.model.CreateStackParam;
 import com.woorea.openstack.heat.model.Events;
+import com.woorea.openstack.heat.model.Resource;
 import com.woorea.openstack.heat.model.Resources;
 import com.woorea.openstack.heat.model.Stack;
 import com.woorea.openstack.heat.model.Stack.Output;
 import com.woorea.openstack.heat.model.Stacks;
-import com.woorea.openstack.keystone.Keystone;
-import com.woorea.openstack.keystone.model.Access;
-import com.woorea.openstack.keystone.model.Authentication;
-import com.woorea.openstack.keystone.utils.KeystoneUtils;
+
 
 @Primary
 @Component
 public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
 
-    private static final String TOKEN_AUTH = "TokenAuth";
+    private static final String CREATE_COMPLETE = "CREATE_COMPLETE";
+
+    private static final String DELETE_COMPLETE = "DELETE_COMPLETE";
+
+    private static final String DELETE_IN_PROGRESS = "DELETE_IN_PROGRESS";
 
-    private static final String QUERY_ALL_STACKS = "QueryAllStacks";
+    private static final String CREATE_IN_PROGRESS = "CREATE_IN_PROGRESS";
 
     private static final String DELETE_STACK = "DeleteStack";
 
@@ -117,30 +115,26 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
     @Autowired
     private Environment environment;
 
-    @Autowired
-    private AuthenticationMethodFactory authenticationMethodFactory;
-
-    @Autowired
-    private MsoTenantUtilsFactory tenantUtilsFactory;
-
-    @Autowired
-    private KeystoneV3Authentication keystoneV3Authentication;
-
     @Autowired
     RequestsDbClient requestDBClient;
 
     @Autowired
     StackStatusHandler statusHandler;
 
+    @Autowired
+    NovaClientImpl novaClient;
+
     private static final Logger logger = LoggerFactory.getLogger(MsoHeatUtils.class);
 
     // Properties names and variables (with default values)
     protected String createPollIntervalProp = "org.onap.so.adapters.po.pollInterval";
     private String deletePollIntervalProp = "org.onap.so.adapters.po.pollInterval";
     private String deletePollTimeoutProp = "org.onap.so.adapters.po.pollTimeout";
+    private String pollingMultiplierProp = "org.onap.so.adapters.po.pollMultiplier";
 
     protected static final String CREATE_POLL_INTERVAL_DEFAULT = "15";
     private static final String DELETE_POLL_INTERVAL_DEFAULT = "15";
+    private static final String pollingMultiplierDefault = "60";
 
     private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
 
@@ -225,6 +219,26 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
             int timeoutMinutes, String environment, Map<String, Object> files, Map<String, Object> heatFiles,
             boolean backout) throws MsoException {
 
+        stripMultiCloudInputs(stackInputs);
+
+        CreateStackParam createStack =
+                createStackParam(stackName, heatTemplate, stackInputs, timeoutMinutes, environment, files, heatFiles);
+        Stack currentStack = createStack(createStack, cloudSiteId, tenantId);
+        currentStack.setStackName(stackName);
+        if (pollForCompletion) {
+            currentStack =
+                    processCreateStack(cloudSiteId, tenantId, timeoutMinutes, backout, currentStack, createStack, true);
+        } else {
+            currentStack =
+                    queryHeatStack(currentStack.getStackName() + "/" + currentStack.getId(), cloudSiteId, tenantId);
+        }
+        return new StackInfoMapper(currentStack).map();
+    }
+
+    /**
+     * @param stackInputs
+     */
+    protected void stripMultiCloudInputs(Map<String, ?> stackInputs) {
         // Take out the multicloud inputs, if present.
         for (String key : MsoMulticloudUtils.MULTICLOUD_INPUTS) {
             if (stackInputs.containsKey(key)) {
@@ -234,36 +248,20 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
                 }
             }
         }
+    }
 
-        CreateStackParam stack =
-                createStackParam(stackName, heatTemplate, stackInputs, timeoutMinutes, environment, files, heatFiles);
-
-        // Obtain the cloud site information where we will create the stack
-        CloudSite cloudSite =
-                cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
-        logger.debug(FOUND, cloudSite);
-        // Get a Heat client. They are cached between calls (keyed by tenantId:cloudId)
-        // This could throw MsoTenantNotFound or MsoOpenstackException (both propagated)
-        Heat heatClient = getHeatClient(cloudSite, tenantId);
-        logger.debug(FOUND, heatClient);
-
-        logger.debug("Ready to Create Stack ({}) with input params: {}", heatTemplate, stackInputs);
-
-        Stack heatStack = null;
+    protected Stack createStack(CreateStackParam stack, String cloudSiteId, String tenantId) throws MsoException {
         try {
-            OpenStackRequest<Stack> request = heatClient.getStacks().create(stack);
-            saveStackRequest(request, MDC.get(ONAPLogConstants.MDCs.REQUEST_ID), stackName);
-            CloudIdentity cloudIdentity = cloudSite.getIdentityService();
-            request.header("X-Auth-User", cloudIdentity.getMsoId());
-            request.header("X-Auth-Key", CryptoUtils.decryptCloudConfigPassword(cloudIdentity.getMsoPass()));
-            heatStack = executeAndRecordOpenstackRequest(request);
+            OpenStackRequest<Stack> request = getHeatClient(cloudSiteId, tenantId).getStacks().create(stack);
+            saveStackRequest(request, MDC.get(ONAPLogConstants.MDCs.REQUEST_ID), stack.getStackName());
+            return executeAndRecordOpenstackRequest(request);
         } catch (OpenStackResponseException e) {
             if (e.getStatus() == 409) {
-                MsoStackAlreadyExists me = new MsoStackAlreadyExists(stackName, tenantId, cloudSiteId);
+                MsoStackAlreadyExists me = new MsoStackAlreadyExists(stack.getStackName(), tenantId, cloudSiteId);
                 me.addContext(CREATE_STACK);
                 throw me;
             } else {
-                logger.debug("ERROR STATUS = {},\n{}\n{}", e.getStatus(), e.getMessage(), e.getLocalizedMessage());
+                logger.error("ERROR STATUS = {},\n{}\n{}", e.getStatus(), e.getMessage(), e.getLocalizedMessage());
                 throw heatExceptionToMsoException(e, CREATE_STACK);
             }
         } catch (OpenStackConnectException e) {
@@ -271,24 +269,79 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
         } catch (RuntimeException e) {
             throw runtimeExceptionToMsoException(e, CREATE_STACK);
         }
+    }
 
-        // Subsequent access by the canonical name "<stack name>/<stack-id>".
-        // Otherwise, simple query by name returns a 302 redirect.
-        // NOTE: This is specific to the v1 Orchestration API.
-        String canonicalName = stackName + "/" + heatStack.getId();
+    protected Stack processCreateStack(String cloudSiteId, String tenantId, int timeoutMinutes, boolean backout,
+            Stack heatStack, CreateStackParam stackCreate, boolean keyPairCleanUp) throws MsoException {
+        Stack latestStack;
+        try {
+            latestStack = pollStackForStatus(timeoutMinutes, heatStack, CREATE_IN_PROGRESS, cloudSiteId, tenantId);
+        } catch (MsoException me) {
+            if (!backout) {
+                logger.info("Exception in Create Stack, stack deletion suppressed", me);
+            } else {
+                logger.info("Exception in Create Stack, stack deletion will be executed", me);
+                handleUnknownCreateStackFailure(heatStack, timeoutMinutes, cloudSiteId, tenantId);
+            }
+            me.addContext(CREATE_STACK);
+            throw me;
+        }
+        return postProcessStackCreate(latestStack, backout, timeoutMinutes, keyPairCleanUp, cloudSiteId, tenantId,
+                stackCreate);
+    }
 
-        if (pollForCompletion) {
-            heatStack = pollStackForCompletion(cloudSiteId, tenantId, stackName, timeoutMinutes, backout, heatClient,
-                    heatStack, canonicalName);
+    protected Stack postProcessStackCreate(Stack stack, boolean backout, int timeoutMinutes, boolean cleanUpKeyPair,
+            String cloudSiteId, String tenantId, CreateStackParam stackCreate) throws MsoException {
+        logger.info("Performing post processing backout: {} cleanUpKeyPair: {}, stack {}", backout, cleanUpKeyPair,
+                stack);
+        if (!CREATE_COMPLETE.equals(stack.getStackStatus())) {
+            if (cleanUpKeyPair && !Strings.isNullOrEmpty(stack.getStackStatusReason())
+                    && isKeyPairFailure(stack.getStackStatusReason())) {
+                return handleKeyPairConflict(cloudSiteId, tenantId, stackCreate, timeoutMinutes, backout, stack);
+            }
+            if (!backout) {
+                logger.info("Status is not CREATE_COMPLETE, stack deletion suppressed");
+                throw new StackCreationException("Stack rollback suppressed, stack not deleted");
+            } else {
+                logger.info("Status is not CREATE_COMPLETE, stack deletion will be executed");
+                Stack deletedStack = handleUnknownCreateStackFailure(stack, timeoutMinutes, cloudSiteId, tenantId);
+                throw new StackCreationException("Stack Creation Failed Openstack Status: " + stack.getStackStatus()
+                        + " Status Reason: " + stack.getStackStatusReason()
+                        + " , Rollback of Stack Creation completed with status: " + deletedStack.getStackStatus()
+                        + " Status Reason: " + deletedStack.getStackStatusReason());
+            }
         } else {
-            // Get initial status, since it will have been null after the create.
-            heatStack = queryHeatStack(heatClient, canonicalName);
-            logger.debug(heatStack.getStackStatus());
+            return stack;
+        }
+    }
+
+    protected Stack pollStackForStatus(int timeoutMinutes, Stack stack, String stackStatus, String cloudSiteId,
+            String tenantId) throws MsoException {
+        int pollingFrequency =
+                Integer.parseInt(this.environment.getProperty(createPollIntervalProp, CREATE_POLL_INTERVAL_DEFAULT));
+        int pollingMultiplier =
+                Integer.parseInt(this.environment.getProperty(pollingMultiplierProp, pollingMultiplierDefault));
+        int numberOfPollingAttempts = Math.floorDiv((timeoutMinutes * pollingMultiplier), pollingFrequency);
+        Heat heatClient = getHeatClient(cloudSiteId, tenantId);
+        Stack latestStack = null;
+        while (true) {
+            latestStack = queryHeatStack(heatClient, stack.getStackName() + "/" + stack.getId());
+            statusHandler.updateStackStatus(stack);
+            logger.debug("Polling: {} ({})", latestStack.getStackStatus(), latestStack.getStackName());
+            if (stackStatus.equals(latestStack.getStackStatus())) {
+                if (numberOfPollingAttempts <= 0) {
+                    logger.error("Polling of stack timed out with Status: {}", latestStack.getStackStatus());
+                    return latestStack;
+                }
+                sleep(pollingFrequency * 1000L);
+                numberOfPollingAttempts -= 1;
+            } else {
+                return latestStack;
+            }
         }
-        return new StackInfoMapper(heatStack).map();
     }
 
-    private void saveStackRequest(OpenStackRequest<Stack> request, String requestId, String stackName) {
+    protected void saveStackRequest(OpenStackRequest<Stack> request, String requestId, String stackName) {
         try {
             ObjectMapper mapper = new ObjectMapper();
             InfraActiveRequests foundRequest = requestDBClient.getInfraActiveRequestbyRequestId(requestId);
@@ -304,209 +357,53 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
         }
     }
 
-    private Stack pollStackForCompletion(String cloudSiteId, String tenantId, String stackName, int timeoutMinutes,
-            boolean backout, Heat heatClient, Stack heatStack, String canonicalName)
-            throws MsoException, MsoOpenstackException {
-        int createPollInterval =
-                Integer.parseInt(this.environment.getProperty(createPollIntervalProp, CREATE_POLL_INTERVAL_DEFAULT));
-        int pollTimeout = (timeoutMinutes * 60) + createPollInterval;
-        int deletePollInterval = createPollInterval;
-        int deletePollTimeout = pollTimeout;
-        boolean createTimedOut = false;
-        StringBuilder stackErrorStatusReason = new StringBuilder("");
-        logger.debug("createPollInterval={}, pollTimeout={}", createPollInterval, pollTimeout);
-
-        while (true) {
-            try {
-                heatStack = queryHeatStack(heatClient, canonicalName);
-                statusHandler.updateStackStatus(heatStack, MDC.get(ONAPLogConstants.MDCs.REQUEST_ID));
-                logger.debug("{} ({})", heatStack.getStackStatus(), canonicalName);
-                try {
-                    logger.debug("Current stack {}", this.getOutputsAsStringBuilder(heatStack).toString());
-                } catch (Exception e) {
-                    logger.debug("an error occurred trying to print out the current outputs of the stack", e);
-                }
+    protected boolean isKeyPairFailure(String errorMessage) {
+        return Pattern.compile(".*Key pair.*already exists.*").matcher(errorMessage).matches();
+    }
 
-                if ("CREATE_IN_PROGRESS".equals(heatStack.getStackStatus())) {
-                    if (pollTimeout <= 0) {
-                        logger.error("{} Cloud site: {} Tenant: {} Stack: {} Stack status: {} {} Create stack timeout",
-                                MessageEnum.RA_CREATE_STACK_TIMEOUT, cloudSiteId, tenantId, stackName,
-                                heatStack.getStackStatus(), ErrorCode.AvailabilityError.getValue());
-                        createTimedOut = true;
-                        break;
-                    }
-                    sleep(createPollInterval * 1000L);
-                    pollTimeout -= createPollInterval;
-                    logger.debug("pollTimeout remaining: {}", pollTimeout);
-                } else {
-                    stackErrorStatusReason.append(
-                            "Stack error (" + heatStack.getStackStatus() + "): " + heatStack.getStackStatusReason());
-                    break;
-                }
-            } catch (MsoException me) {
-                // Cannot query the stack status. Something is wrong.
-                // Try to roll back the stack
-                if (!backout) {
-                    logger.warn("{} Exception in Create Stack, stack deletion suppressed {}",
-                            MessageEnum.RA_CREATE_STACK_ERR, ErrorCode.BusinessProcesssError.getValue());
-                } else {
-                    try {
-                        logger.debug(
-                                "Create Stack error - unable to query for stack status - attempting to delete stack: {}"
-                                        + " - This will likely fail and/or we won't be able to query to see if delete worked",
-                                canonicalName);
-                        OpenStackRequest<Void> request = heatClient.getStacks().deleteByName(canonicalName);
-                        executeAndRecordOpenstackRequest(request);
-                        boolean deleted = false;
-                        while (!deleted) {
-                            try {
-                                heatStack = queryHeatStack(heatClient, canonicalName);
-                                statusHandler.updateStackStatus(heatStack, MDC.get(ONAPLogConstants.MDCs.REQUEST_ID));
-                                if (heatStack != null) {
-                                    logger.debug(heatStack.getStackStatus());
-                                    if ("DELETE_IN_PROGRESS".equals(heatStack.getStackStatus())) {
-                                        if (deletePollTimeout <= 0) {
-                                            logger.error(
-                                                    "{} Cloud site: {} Tenant: {} Stack: {} Stack status: {} {} Rollback: DELETE stack timeout",
-                                                    MessageEnum.RA_CREATE_STACK_TIMEOUT, cloudSiteId, tenantId,
-                                                    stackName, heatStack.getStackStatus(),
-                                                    ErrorCode.AvailabilityError.getValue());
-                                            break;
-                                        } else {
-                                            sleep(deletePollInterval * 1000L);
-                                            deletePollTimeout -= deletePollInterval;
-                                        }
-                                    } else if ("DELETE_COMPLETE".equals(heatStack.getStackStatus())) {
-                                        logger.debug("DELETE_COMPLETE for {}", canonicalName);
-                                        deleted = true;
-                                        continue;
-                                    } else {
-                                        // got a status other than DELETE_IN_PROGRESS or DELETE_COMPLETE - so break and
-                                        // evaluate
-                                        break;
-                                    }
-                                } else {
-                                    // assume if we can't find it - it's deleted
-                                    logger.debug("heatStack returned null - assume the stack {} has been deleted",
-                                            canonicalName);
-                                    deleted = true;
-                                    continue;
-                                }
-
-                            } catch (Exception e3) {
-                                // Just log this one. We will report the original exception.
-                                logger.error(EXCEPTION_ROLLING_BACK_STACK, MessageEnum.RA_CREATE_STACK_ERR,
-                                        ErrorCode.BusinessProcesssError.getValue(), e3);
-                            }
-                        }
-                    } catch (Exception e2) {
-                        // Just log this one. We will report the original exception.
-                        logger.error(EXCEPTION_ROLLING_BACK_STACK, MessageEnum.RA_CREATE_STACK_ERR,
-                                ErrorCode.BusinessProcesssError.getValue(), e2);
-                    }
-                }
+    protected Stack handleUnknownCreateStackFailure(Stack stack, int timeoutMinutes, String cloudSiteId,
+            String tenantId) throws MsoException {
+        if (stack != null && !Strings.isNullOrEmpty(stack.getStackName()) && !Strings.isNullOrEmpty(stack.getId())) {
+            OpenStackRequest<Void> request = getHeatClient(cloudSiteId, tenantId).getStacks()
+                    .deleteByName(stack.getStackName() + "/" + stack.getId());
+            executeAndRecordOpenstackRequest(request);
+            Stack currentStack = pollStackForStatus(timeoutMinutes, stack, DELETE_IN_PROGRESS, cloudSiteId, tenantId);
+            postProcessStackDelete(currentStack);
+            return currentStack;
+        } else {
+            throw new StackCreationException("Cannot Find Stack Name or Id");
+        }
+    }
 
-                // Propagate the original exception from Stack Query.
-                me.addContext(CREATE_STACK);
-                throw me;
-            }
+    protected void postProcessStackDelete(Stack stack) throws MsoException {
+        logger.info("Performing post processing on delete stack {}", stack);
+        if (stack != null && !Strings.isNullOrEmpty(stack.getStackStatus())) {
+            if (!DELETE_COMPLETE.equals(stack.getStackStatus()))
+                throw new StackRollbackException("Stack Deletion completed with status: " + stack.getStackStatus()
+                        + " Status Reason: " + stack.getStackStatusReason());
+        } else {
+            throw new StackRollbackException("Cannot Find Stack Name or Id");
         }
+    }
 
-        if (!"CREATE_COMPLETE".equals(heatStack.getStackStatus())) {
-            logger.error("{} Create Stack error:  Polling complete with non-success status: {}, {} {} ",
-                    MessageEnum.RA_CREATE_STACK_ERR, heatStack.getStackStatus(), heatStack.getStackStatusReason(),
-                    ErrorCode.BusinessProcesssError.getValue());
+    protected Stack handleKeyPairConflict(String cloudSiteId, String tenantId, CreateStackParam stackCreate,
+            int timeoutMinutes, boolean backout, Stack stack) throws MsoException {
+        logger.info("Keypair conflict found on stack, attempting to clean up");
 
-            // Rollback the stack creation, since it is in an indeterminate state.
-            if (!backout) {
-                logger.warn(
-                        "{} Create Stack errored, stack deletion suppressed {} Create Stack error, stack deletion suppressed",
-                        MessageEnum.RA_CREATE_STACK_ERR, ErrorCode.BusinessProcesssError.getValue());
-            } else {
-                try {
-                    logger.debug("Create Stack errored - attempting to DELETE stack: {}", canonicalName);
-                    logger.debug("deletePollInterval={}, deletePollTimeout={}", deletePollInterval, deletePollTimeout);
-                    OpenStackRequest<Void> request = heatClient.getStacks().deleteByName(canonicalName);
-                    executeAndRecordOpenstackRequest(request);
-                    boolean deleted = false;
-                    while (!deleted) {
-                        try {
-                            heatStack = queryHeatStack(heatClient, canonicalName);
-                            if (heatStack != null) {
-                                logger.debug("{} ({})", heatStack.getStackStatus(), canonicalName);
-                                if ("DELETE_IN_PROGRESS".equals(heatStack.getStackStatus())) {
-                                    if (deletePollTimeout <= 0) {
-                                        logger.error(
-                                                "{} Cloud site: {} Tenant: {} Stack: {} Stack status: {} {} Rollback: DELETE stack timeout",
-                                                MessageEnum.RA_CREATE_STACK_TIMEOUT, cloudSiteId, tenantId, stackName,
-                                                heatStack.getStackStatus(), ErrorCode.AvailabilityError.getValue());
-                                        break;
-                                    } else {
-                                        sleep(deletePollInterval * 1000L);
-                                        deletePollTimeout -= deletePollInterval;
-                                        logger.debug("deletePollTimeout remaining: {}", deletePollTimeout);
-                                    }
-                                } else if ("DELETE_COMPLETE".equals(heatStack.getStackStatus())) {
-                                    logger.debug("DELETE_COMPLETE for {}", canonicalName);
-                                    deleted = true;
-                                    continue;
-                                } else if ("DELETE_FAILED".equals(heatStack.getStackStatus())) {
-                                    // Warn about this (?) - but still throw the original exception
-                                    logger.warn(
-                                            "{} Create Stack errored, stack deletion FAILED {} Create Stack error, stack deletion FAILED",
-                                            MessageEnum.RA_CREATE_STACK_ERR,
-                                            ErrorCode.BusinessProcesssError.getValue());
-                                    logger.debug(
-                                            "Stack deletion FAILED on a rollback of a create - {}, status={}, reason={}",
-                                            canonicalName, heatStack.getStackStatus(),
-                                            heatStack.getStackStatusReason());
-                                    break;
-                                } else {
-                                    // got a status other than DELETE_IN_PROGRESS or DELETE_COMPLETE - so break and
-                                    // evaluate
-                                    break;
-                                }
-                            } else {
-                                // assume if we can't find it - it's deleted
-                                logger.debug("heatStack returned null - assume the stack {} has been deleted",
-                                        canonicalName);
-                                deleted = true;
-                                continue;
-                            }
-
-                        } catch (MsoException me2) {
-                            // We got an exception on the delete - don't throw this exception - throw the original -
-                            // just log.
-                            logger.debug("Exception thrown trying to delete {} on a create->rollback: {} ",
-                                    canonicalName, me2.getContextMessage(), me2);
-                            logger.warn("{} Create Stack errored, then stack deletion FAILED - exception thrown {} {}",
-                                    MessageEnum.RA_CREATE_STACK_ERR, ErrorCode.BusinessProcesssError.getValue(),
-                                    me2.getContextMessage());
-                        }
-
-                    } // end while !deleted
-                    StringBuilder errorContextMessage;
-                    if (createTimedOut) {
-                        errorContextMessage = new StringBuilder("Stack Creation Timeout");
-                    } else {
-                        errorContextMessage = stackErrorStatusReason;
-                    }
-                    if (deleted) {
-                        errorContextMessage.append(" - stack successfully deleted");
-                    } else {
-                        errorContextMessage.append(" - encountered an error trying to delete the stack");
-                    }
-                } catch (Exception e2) {
-                    // shouldn't happen - but handle
-                    logger.error(EXCEPTION_ROLLING_BACK_STACK, MessageEnum.RA_CREATE_STACK_ERR,
-                            ErrorCode.BusinessProcesssError.getValue(), e2);
-                }
+        Resources resources = queryStackResources(cloudSiteId, tenantId, stackCreate.getStackName(), 2);
+        List<Resource> keyPairs = resources.getList().stream()
+                .filter(p -> "OS::Nova::KeyPair".equalsIgnoreCase(p.getType())).collect(Collectors.toList());
+        keyPairs.stream().forEach(keyPair -> {
+            try {
+                novaClient.deleteKeyPair(cloudSiteId, tenantId, keyPair.getPhysicalResourceId());
+            } catch (MsoCloudSiteNotFound | NovaClientException e) {
+                logger.warn("Could not delete keypair", e);
             }
-            MsoOpenstackException me = new MsoOpenstackException(0, "", stackErrorStatusReason.toString());
-            me.addContext(CREATE_STACK);
-            throw me;
-        }
-        return heatStack;
+        });
+        handleUnknownCreateStackFailure(stack, timeoutMinutes, cloudSiteId, tenantId);
+        Stack newStack = createStack(stackCreate, cloudSiteId, tenantId);
+        newStack.setStackName(stackCreate.getStackName());
+        return processCreateStack(cloudSiteId, tenantId, timeoutMinutes, backout, newStack, stackCreate, false);
     }
 
     /**
@@ -523,19 +420,9 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
     public StackInfo queryStack(String cloudSiteId, String cloudOwner, String tenantId, String stackName)
             throws MsoException {
         logger.debug("Query HEAT stack: {} in tenant {}", stackName, tenantId);
-
-        // Obtain the cloud site information where we will create the stack
-        CloudSite cloudSite =
-                cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
-        logger.debug(FOUND, cloudSite.toString());
-
-        // Get a Heat client. They are cached between calls (keyed by tenantId:cloudId)
         Heat heatClient = null;
         try {
-            heatClient = getHeatClient(cloudSite, tenantId);
-            if (heatClient != null) {
-                logger.debug(FOUND, heatClient.toString());
-            }
+            heatClient = getHeatClient(cloudSiteId, tenantId);
         } catch (MsoTenantNotFound e) {
             // Tenant doesn't exist, so stack doesn't either
             logger.debug("Tenant with id " + tenantId + "not found.", e);
@@ -583,11 +470,9 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
      */
     public StackInfo deleteStack(String tenantId, String cloudOwner, String cloudSiteId, String stackName,
             boolean pollForCompletion) throws MsoException {
-        CloudSite cloudSite =
-                cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
         Heat heatClient = null;
         try {
-            heatClient = getHeatClient(cloudSite, tenantId);
+            heatClient = getHeatClient(cloudSiteId, tenantId);
         } catch (MsoTenantNotFound e) {
             logger.debug("Tenant with id " + tenantId + "not found.", e);
             return new StackInfo(stackName, HeatStatus.NOTFOUND);
@@ -600,7 +485,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
 
         // OK if stack not found, perform a query first
         Stack heatStack = queryHeatStack(heatClient, stackName);
-        if (heatStack == null || "DELETE_COMPLETE".equals(heatStack.getStackStatus())) {
+        if (heatStack == null || DELETE_COMPLETE.equals(heatStack.getStackStatus())) {
             // Not found. Return a StackInfo with status NOTFOUND
             return new StackInfo(stackName, HeatStatus.NOTFOUND);
         }
@@ -637,16 +522,16 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
         // Requery the stack for current status.
         // It will probably still exist with "DELETE_IN_PROGRESS" status.
         heatStack = queryHeatStack(heatClient, canonicalName);
-        statusHandler.updateStackStatus(heatStack, MDC.get(ONAPLogConstants.MDCs.REQUEST_ID));
+        statusHandler.updateStackStatus(heatStack);
         if (pollForCompletion) {
             int pollInterval = Integer
                     .parseInt(this.environment.getProperty(deletePollIntervalProp, "" + DELETE_POLL_INTERVAL_DEFAULT));
             int pollTimeout = Integer
                     .parseInt(this.environment.getProperty(deletePollTimeoutProp, "" + DELETE_POLL_INTERVAL_DEFAULT));
-            statusHandler.updateStackStatus(heatStack, MDC.get(ONAPLogConstants.MDCs.REQUEST_ID));
+            statusHandler.updateStackStatus(heatStack);
             // When querying by canonical name, Openstack returns DELETE_COMPLETE status
             // instead of "404" (which would result from query by stack name).
-            while (heatStack != null && !"DELETE_COMPLETE".equals(heatStack.getStackStatus())) {
+            while (heatStack != null && !DELETE_COMPLETE.equals(heatStack.getStackStatus())) {
                 logger.debug("Stack status: {}", heatStack.getStackStatus());
 
                 if ("DELETE_FAILED".equals(heatStack.getStackStatus())) {
@@ -694,58 +579,6 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
         return stackInfo;
     }
 
-    /**
-     * Query for all stacks in a tenant site. This call will return a List of StackInfo objects, one for each deployed
-     * stack.
-     *
-     * Note that this is limited to a single site. To ensure that a tenant is truly empty would require looping across
-     * all tenant endpoints.
-     *
-     * @param tenantId The Openstack ID of the tenant to query
-     * @param cloudSiteId The cloud identifier (may be a region) in which to query.
-     * @return A List of StackInfo objects
-     * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception.
-     * @throws MsoCloudSiteNotFound
-     */
-    public List<StackInfo> queryAllStacks(String tenantId, String cloudSiteId) throws MsoException {
-        // Obtain the cloud site information where we will create the stack
-        CloudSite cloudSite =
-                cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
-        // Get a Heat client. They are cached between calls (keyed by tenantId:cloudId)
-        Heat heatClient = getHeatClient(cloudSite, tenantId);
-
-        try {
-            OpenStackRequest<Stacks> request = heatClient.getStacks().list();
-            Stacks stacks = executeAndRecordOpenstackRequest(request);
-
-            List<StackInfo> stackList = new ArrayList<>();
-
-            // Not sure if returns an empty list or null if no stacks exist
-            if (stacks != null) {
-                for (Stack stack : stacks) {
-                    stackList.add(new StackInfoMapper(stack).map());
-                }
-            }
-
-            return stackList;
-        } catch (OpenStackResponseException e) {
-            if (e.getStatus() == 404) {
-                // Not sure if this can happen, but return an empty list
-                logger.debug("queryAllStacks - stack not found: ");
-                return new ArrayList<>();
-            } else {
-                // Convert the OpenStackResponseException to an MsoOpenstackException
-                throw heatExceptionToMsoException(e, QUERY_ALL_STACKS);
-            }
-        } catch (OpenStackConnectException e) {
-            // Error connecting to Openstack instance. Convert to an MsoException
-            throw heatExceptionToMsoException(e, QUERY_ALL_STACKS);
-        } catch (RuntimeException e) {
-            // Catch-all
-            throw runtimeExceptionToMsoException(e, QUERY_ALL_STACKS);
-        }
-    }
-
     /**
      * Validate parameters to be passed to Heat template. This method performs three functions: 1. Apply default values
      * to parameters which have them defined 2. Report any required parameters that are missing. This will generate an
@@ -802,8 +635,6 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
         return updatedParams;
     }
 
-    // ---------------------------------------------------------------
-    // PRIVATE FUNCTIONS FOR USE WITHIN THIS CLASS
 
     /**
      * Get a Heat client for the Openstack Identity service. This requires a 'member'-level userId + password, which
@@ -815,76 +646,10 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
      *
      * @return an authenticated Heat object
      */
-    public Heat getHeatClient(CloudSite cloudSite, String tenantId) throws MsoException {
-        String cloudId = cloudSite.getId();
-        // For DCP/LCP, the region should be the cloudId.
-        String region = cloudSite.getRegionId();
-
-        // Obtain an MSO token for the tenant
-        CloudIdentity cloudIdentity = cloudSite.getIdentityService();
-        logger.debug(FOUND, cloudIdentity.toString());
-        MsoTenantUtils tenantUtils =
-                tenantUtilsFactory.getTenantUtilsByServerType(cloudIdentity.getIdentityServerType());
-        String keystoneUrl = tenantUtils.getKeystoneUrl(cloudId, cloudIdentity);
-        logger.debug("keystoneUrl={}", keystoneUrl);
-        String heatUrl = null;
-        String tokenId = null;
-        try {
-            if (ServerType.KEYSTONE.equals(cloudIdentity.getIdentityServerType())) {
-                Keystone keystoneTenantClient = new Keystone(keystoneUrl);
-                Access access = null;
-
-                Authentication credentials = authenticationMethodFactory.getAuthenticationFor(cloudIdentity);
-
-                OpenStackRequest<Access> request =
-                        keystoneTenantClient.tokens().authenticate(credentials).withTenantId(tenantId);
-
-                access = executeAndRecordOpenstackRequest(request);
-
-                try {
-                    logger.debug("access={}", access.toString());
-                    heatUrl = KeystoneUtils.findEndpointURL(access.getServiceCatalog(), "orchestration", region,
-                            "public");
-                    logger.debug("heatUrl={}, region={}", heatUrl, region);
-                } catch (RuntimeException e) {
-                    // This comes back for not found (probably an incorrect region ID)
-                    String error = "AIC did not match an orchestration service for: region=" + region + ",cloud="
-                            + cloudIdentity.getIdentityUrl();
-                    throw new MsoAdapterException(error, e);
-                }
-                tokenId = access.getToken().getId();
-            } else if (ServerType.KEYSTONE_V3.equals(cloudIdentity.getIdentityServerType())) {
-                try {
-                    KeystoneAuthHolder holder = keystoneV3Authentication.getToken(cloudSite, tenantId, "orchestration");
-                    tokenId = holder.getId();
-                    heatUrl = holder.getServiceUrl();
-                } catch (ServiceEndpointNotFoundException e) {
-                    // This comes back for not found (probably an incorrect region ID)
-                    String error = "cloud did not match an orchestration service for: region=" + region + ",cloud="
-                            + cloudIdentity.getIdentityUrl();
-                    throw new MsoAdapterException(error, e);
-                }
-            }
-        } catch (OpenStackResponseException e) {
-            if (e.getStatus() == 401) {
-                // Authentication error.
-                String error = "Authentication Failure: tenant=" + tenantId + ",cloud=" + cloudIdentity.getId();
-
-                throw new MsoAdapterException(error);
-            } else {
-                throw keystoneErrorToMsoException(e, TOKEN_AUTH);
-            }
-        } catch (OpenStackConnectException e) {
-            // Connection to Openstack failed
-            MsoIOException me = new MsoIOException(e.getMessage(), e);
-            me.addContext(TOKEN_AUTH);
-            throw me;
-        } catch (RuntimeException e) {
-            // Catch-all
-            throw runtimeExceptionToMsoException(e, TOKEN_AUTH);
-        }
-        Heat heatClient = new Heat(heatUrl);
-        heatClient.token(tokenId);
+    public Heat getHeatClient(String cloudSiteId, String tenantId) throws MsoException {
+        KeystoneAuthHolder keystone = getKeystoneAuthHolder(cloudSiteId, tenantId, "orchestration");
+        Heat heatClient = new Heat(keystone.getServiceUrl());
+        heatClient.token(keystone.getId());
         return heatClient;
     }
 
@@ -928,6 +693,13 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
         }
     }
 
+    public Stack queryHeatStack(String stackName, String cloudSiteId, String tenantId) throws MsoException {
+        if (stackName == null) {
+            return null;
+        }
+        return queryHeatStack(getHeatClient(cloudSiteId, tenantId), stackName);
+    }
+
 
     public Map<String, Object> queryStackForOutputs(String cloudSiteId, String cloudOwner, String tenantId,
             String stackName) throws MsoException {
@@ -990,42 +762,6 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
         return;
     }
 
-    public StringBuilder requestToStringBuilder(CreateStackParam stack) {
-        StringBuilder sb = new StringBuilder();
-        sb.append("Stack:\n");
-        sb.append("\tStackName: " + stack.getStackName());
-        sb.append("\tTemplateUrl: " + stack.getTemplateUrl());
-        sb.append("\tTemplate: " + stack.getTemplate());
-        sb.append("\tEnvironment: " + stack.getEnvironment());
-        sb.append("\tTimeout: " + stack.getTimeoutMinutes());
-        sb.append("\tParameters:\n");
-        Map<String, Object> params = stack.getParameters();
-        if (params == null || params.size() < 1) {
-            sb.append("\nNONE");
-        } else {
-            for (String key : params.keySet()) {
-                if (params.get(key) instanceof String) {
-                    sb.append("\n").append(key).append("=").append((String) params.get(key));
-                } else if (params.get(key) instanceof JsonNode) {
-                    String jsonStringOut = this.convertNode((JsonNode) params.get(key));
-                    sb.append("\n").append(key).append("=").append(jsonStringOut);
-                } else if (params.get(key) instanceof Integer) {
-                    String integerOut = "" + params.get(key);
-                    sb.append("\n").append(key).append("=").append(integerOut);
-
-                } else {
-                    try {
-                        String str = params.get(key).toString();
-                        sb.append("\n").append(key).append("=").append(str);
-                    } catch (Exception e) {
-                        logger.debug("Exception :", e);
-                    }
-                }
-            }
-        }
-        return sb;
-    }
-
     private String convertNode(final JsonNode node) {
         try {
             final Object obj = JSON_MAPPER.treeToValue(node, Object.class);
@@ -1193,44 +929,32 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
         HashMap<String, HeatTemplateParam> paramAliases = new HashMap<>();
 
         if (inputs == null) {
-            logger.debug("convertInputMap - inputs is null - nothing to do here");
             return new HashMap<>();
         }
-
-        logger.debug("convertInputMap in MsoHeatUtils called, with {} inputs, and template {}", inputs.size(),
-                template.getArtifactUuid());
         try {
-            logger.debug(template.toString());
             Set<HeatTemplateParam> paramSet = template.getParameters();
-            logger.debug("paramSet has {} entries", paramSet.size());
         } catch (Exception e) {
             logger.debug("Exception occurred in convertInputMap {} :", e.getMessage(), e);
         }
 
         for (HeatTemplateParam htp : template.getParameters()) {
-            logger.debug("Adding {}", htp.getParamName());
             params.put(htp.getParamName(), htp);
             if (htp.getParamAlias() != null && !"".equals(htp.getParamAlias())) {
                 logger.debug("\tFound ALIAS {} -> {}", htp.getParamName(), htp.getParamAlias());
                 paramAliases.put(htp.getParamAlias(), htp);
             }
         }
-        logger.debug("Now iterate through the inputs...");
+
         for (String key : inputs.keySet()) {
-            logger.debug("key={}", key);
             boolean alias = false;
             String realName = null;
             if (!params.containsKey(key)) {
-                logger.debug("{} is not a parameter in the template! - check for an alias", key);
                 // add check here for an alias
                 if (!paramAliases.containsKey(key)) {
-                    logger.debug("The parameter {} is in the inputs, but it's not a parameter for this template - omit",
-                            key);
                     continue;
                 } else {
                     alias = true;
                     realName = paramAliases.get(key).getParamName();
-                    logger.debug("FOUND AN ALIAS! Will use {} in lieu of give key/alias {}", realName, key);
                 }
             }
             String type = params.get(key).getParamType();
@@ -1238,7 +962,6 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
                 logger.debug("**PARAM_TYPE is null/empty for {}, will default to string", key);
                 type = "string";
             }
-            logger.debug("Parameter: {} is of type {}", key, type);
             if ("string".equalsIgnoreCase(type)) {
                 // Easiest!
                 String str = inputs.get(key) != null ? inputs.get(key).toString() : null;
@@ -1507,9 +1230,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
 
     public Resources queryStackResources(String cloudSiteId, String tenantId, String stackName, int nestedDepth)
             throws MsoException {
-        CloudSite cloudSite =
-                cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
-        Heat heatClient = getHeatClient(cloudSite, tenantId);
+        Heat heatClient = getHeatClient(cloudSiteId, tenantId);
         OpenStackRequest<Resources> request =
                 heatClient.getResources().listResources(stackName).queryParam("nested_depth", nestedDepth);
         return executeAndRecordOpenstackRequest(request);
@@ -1517,9 +1238,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
 
     public Events queryStackEvents(String cloudSiteId, String tenantId, String stackName, String stackId,
             int nestedDepth) throws MsoException {
-        CloudSite cloudSite =
-                cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
-        Heat heatClient = getHeatClient(cloudSite, tenantId);
+        Heat heatClient = getHeatClient(cloudSiteId, tenantId);
         OpenStackRequest<Events> request =
                 heatClient.getEvents().listEvents(stackName, stackId).queryParam("nested_depth", nestedDepth);
         return executeAndRecordOpenstackRequest(request);
@@ -1527,11 +1246,9 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
 
     public Stacks queryStacks(String cloudSiteId, String tenantId, int limit, String marker)
             throws MsoCloudSiteNotFound, HeatClientException {
-        CloudSite cloudSite =
-                cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
         Heat heatClient;
         try {
-            heatClient = getHeatClient(cloudSite, tenantId);
+            heatClient = getHeatClient(cloudSiteId, tenantId);
         } catch (MsoException e) {
             logger.error("Error Creating Heat Client", e);
             throw new HeatClientException("Error Creating Heat Client", e);
@@ -1543,9 +1260,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin {
 
     public <R> R executeHeatClientRequest(String url, String cloudSiteId, String tenantId, Class<R> returnType)
             throws MsoException {
-        CloudSite cloudSite =
-                cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
-        Heat heatClient = getHeatClient(cloudSite, tenantId);
+        Heat heatClient = getHeatClient(cloudSiteId, tenantId);
         OpenStackRequest<R> request = heatClient.get(url, returnType);
         return executeAndRecordOpenstackRequest(request);
     }
index a2e386a..684fe98 100644 (file)
 package org.onap.so.openstack.utils;
 
 
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.woorea.openstack.base.client.OpenStackBaseException;
-import com.woorea.openstack.base.client.OpenStackRequest;
-import com.woorea.openstack.heat.Heat;
-import com.woorea.openstack.heat.model.Stack;
-import com.woorea.openstack.heat.model.Stack.Output;
-import com.woorea.openstack.heat.model.UpdateStackParam;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import org.onap.so.db.catalog.beans.CloudSite;
 import org.onap.so.logger.ErrorCode;
 import org.onap.so.logger.MessageEnum;
 import org.onap.so.openstack.beans.StackInfo;
-import org.onap.so.openstack.exceptions.MsoCloudSiteNotFound;
 import org.onap.so.openstack.exceptions.MsoException;
 import org.onap.so.openstack.exceptions.MsoOpenstackException;
 import org.onap.so.openstack.exceptions.MsoStackNotFound;
@@ -52,6 +41,15 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Component;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.woorea.openstack.base.client.OpenStackBaseException;
+import com.woorea.openstack.base.client.OpenStackRequest;
+import com.woorea.openstack.heat.Heat;
+import com.woorea.openstack.heat.model.Stack;
+import com.woorea.openstack.heat.model.Stack.Output;
+import com.woorea.openstack.heat.model.UpdateStackParam;
 
 @Component
 public class MsoHeatUtilsWithUpdate extends MsoHeatUtils {
@@ -138,12 +136,7 @@ public class MsoHeatUtilsWithUpdate extends MsoHeatUtils {
             haveHeatFiles = false;
         }
 
-        // Obtain the cloud site information where we will create the stack
-        CloudSite cloudSite =
-                cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
-        // Get a Heat client. They are cached between calls (keyed by tenantId:cloudId)
-        // This could throw MsoTenantNotFound or MsoOpenstackException (both propagated)
-        Heat heatClient = getHeatClient(cloudSite, tenantId);
+        Heat heatClient = getHeatClient(cloudSiteId, tenantId);
 
         // Perform a query first to get the current status
         Stack heatStack = queryHeatStack(heatClient, stackName);
index ab93a6c..f74a3f5 100644 (file)
 package org.onap.so.openstack.utils;
 
 
-import com.woorea.openstack.base.client.OpenStackBaseException;
-import com.woorea.openstack.base.client.OpenStackConnectException;
-import com.woorea.openstack.base.client.OpenStackRequest;
-import com.woorea.openstack.base.client.OpenStackResponseException;
-import com.woorea.openstack.keystone.Keystone;
-import com.woorea.openstack.keystone.model.Access;
-import com.woorea.openstack.keystone.model.Authentication;
-import com.woorea.openstack.keystone.model.Metadata;
-import com.woorea.openstack.keystone.model.Role;
-import com.woorea.openstack.keystone.model.Roles;
-import com.woorea.openstack.keystone.model.Tenant;
-import com.woorea.openstack.keystone.model.User;
-import com.woorea.openstack.keystone.utils.KeystoneUtils;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Optional;
@@ -54,6 +41,19 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import com.woorea.openstack.base.client.OpenStackBaseException;
+import com.woorea.openstack.base.client.OpenStackConnectException;
+import com.woorea.openstack.base.client.OpenStackRequest;
+import com.woorea.openstack.base.client.OpenStackResponseException;
+import com.woorea.openstack.keystone.Keystone;
+import com.woorea.openstack.keystone.model.Access;
+import com.woorea.openstack.keystone.model.Authentication;
+import com.woorea.openstack.keystone.model.Metadata;
+import com.woorea.openstack.keystone.model.Role;
+import com.woorea.openstack.keystone.model.Roles;
+import com.woorea.openstack.keystone.model.Tenant;
+import com.woorea.openstack.keystone.model.User;
+import com.woorea.openstack.keystone.utils.KeystoneUtils;
 
 @Component
 public class MsoKeystoneUtils extends MsoTenantUtils {
@@ -414,7 +414,6 @@ public class MsoKeystoneUtils extends MsoTenantUtils {
         // Get the Identity service URL. Throws runtime exception if not found per region.
         String adminUrl = null;
         try {
-            // TODO: FOR TESTING!!!!
             adminUrl = KeystoneUtils.findEndpointURL(access.getServiceCatalog(), "identity", region, "public");
             adminUrl = adminUrl.replaceFirst("5000", "35357");
         } catch (RuntimeException e) {
index a342f77..6cd79de 100644 (file)
@@ -183,4 +183,25 @@ public class NovaClientImpl extends MsoCommonUtils {
         }
     }
 
+    /**
+     * Deletes a keypair inside openstack
+     *
+     * 
+     * @param cloudSiteId the cloud site id
+     * @param tenantId the tenant id
+     * @param keyPairName name of the keypair to be deleted
+     * @throws MsoCloudSiteNotFound the mso cloud site not found
+     * @throws NeutronClientException if the client cannot be built this is thrown
+     */
+    public void deleteKeyPair(String cloudSiteId, String tenantId, String keyPairName)
+            throws MsoCloudSiteNotFound, NovaClientException {
+        try {
+            Nova novaClient = getNovaClient(cloudSiteId, tenantId);
+            OpenStackRequest<Void> request = novaClient.keyPairs().delete(keyPairName);
+            executeAndRecordOpenstackRequest(request);
+        } catch (MsoException e) {
+            logger.error("Error building Nova Client", e);
+            throw new NovaClientException("Error building Nova Client", e);
+        }
+    }
 }
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/StackCreationException.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/StackCreationException.java
new file mode 100644 (file)
index 0000000..3a377ef
--- /dev/null
@@ -0,0 +1,11 @@
+package org.onap.so.openstack.utils;
+
+import org.onap.so.openstack.exceptions.MsoException;
+
+public class StackCreationException extends MsoException {
+
+    public StackCreationException(String error) {
+        super(error);
+    }
+
+}
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/StackResultWrapper.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/StackResultWrapper.java
new file mode 100644 (file)
index 0000000..c3b3c1d
--- /dev/null
@@ -0,0 +1,62 @@
+package org.onap.so.openstack.utils;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import com.woorea.openstack.heat.model.Stack;
+
+public class StackResultWrapper {
+
+    private Stack stack;
+    private boolean stackTimedOutPolling;
+    private boolean stackNotFound;
+    private String errorMessage;
+    private String errorCode;
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this).append("stack", stack).append("stackTimedOutPolling", stackTimedOutPolling)
+                .append("stackNotFound", stackNotFound).append("errorMessage", errorMessage)
+                .append("errorCode", errorCode).toString();
+    }
+
+    public Stack getStack() {
+        return stack;
+    }
+
+    public void setStack(Stack stack) {
+        this.stack = stack;
+    }
+
+    public boolean isStackTimedOutPolling() {
+        return stackTimedOutPolling;
+    }
+
+    public void setStackTimedOutPolling(boolean stackTimedOutPolling) {
+        this.stackTimedOutPolling = stackTimedOutPolling;
+    }
+
+    public boolean isStackNotFound() {
+        return stackNotFound;
+    }
+
+    public void setStackNotFound(boolean stackNotFound) {
+        this.stackNotFound = stackNotFound;
+    }
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+
+    public void setErrorMessage(String errorMessage) {
+        this.errorMessage = errorMessage;
+    }
+
+    public String getErrorCode() {
+        return errorCode;
+    }
+
+    public void setErrorCode(String errorCode) {
+        this.errorCode = errorCode;
+    }
+
+
+}
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/StackRollbackException.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/StackRollbackException.java
new file mode 100644 (file)
index 0000000..1bad7ef
--- /dev/null
@@ -0,0 +1,11 @@
+package org.onap.so.openstack.utils;
+
+import org.onap.so.openstack.exceptions.MsoException;
+
+public class StackRollbackException extends MsoException {
+
+    public StackRollbackException(String error) {
+        super(error);
+    }
+
+}
index 990e9a4..53337b3 100644 (file)
@@ -1,10 +1,12 @@
 package org.onap.so.openstack.utils;
 
 
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
 import org.onap.so.db.request.beans.RequestProcessingData;
 import org.onap.so.db.request.client.RequestsDbClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
@@ -21,8 +23,9 @@ public class StackStatusHandler {
     private RequestsDbClient requestDBClient;
 
     @Async
-    public void updateStackStatus(Stack stack, String requestId) {
+    public void updateStackStatus(Stack stack) {
         try {
+            String requestId = MDC.get(ONAPLogConstants.MDCs.REQUEST_ID);
             String stackStatus = mapper.writeValueAsString(stack);
             RequestProcessingData requestProcessingData =
                     requestDBClient.getRequestProcessingDataBySoRequestIdAndNameAndGrouping(requestId, stack.getId(),
diff --git a/adapters/mso-adapter-utils/src/test/java/org/onap/so/openstack/utils/MsoHeatUtilsITTest.java b/adapters/mso-adapter-utils/src/test/java/org/onap/so/openstack/utils/MsoHeatUtilsITTest.java
new file mode 100644 (file)
index 0000000..7e783aa
--- /dev/null
@@ -0,0 +1,219 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2018 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.openstack.utils;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
+import static com.shazam.shazamcrest.MatcherAssert.assertThat;
+import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs;
+import static org.junit.Assert.assertNotNull;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.http.HttpStatus;
+import org.junit.Assert;
+import org.junit.Test;
+import org.onap.so.BaseTest;
+import org.onap.so.StubOpenStack;
+import org.onap.so.adapters.vdu.CloudInfo;
+import org.onap.so.adapters.vdu.PluginAction;
+import org.onap.so.adapters.vdu.VduArtifact;
+import org.onap.so.adapters.vdu.VduArtifact.ArtifactType;
+import org.onap.so.adapters.vdu.VduInstance;
+import org.onap.so.adapters.vdu.VduModelInfo;
+import org.onap.so.adapters.vdu.VduStateType;
+import org.onap.so.adapters.vdu.VduStatus;
+import org.onap.so.db.catalog.beans.CloudIdentity;
+import org.onap.so.db.catalog.beans.CloudSite;
+import org.onap.so.openstack.beans.StackInfo;
+import org.onap.so.openstack.exceptions.MsoAdapterException;
+import org.onap.so.openstack.exceptions.MsoException;
+import org.onap.so.openstack.exceptions.MsoOpenstackException;
+import org.springframework.beans.factory.annotation.Autowired;
+import com.woorea.openstack.heat.Heat;
+
+public class MsoHeatUtilsITTest extends BaseTest {
+
+    @Autowired
+    private MsoHeatUtils heatUtils;
+
+    @Test
+    public void instantiateVduTest() throws MsoException, IOException {
+        VduInstance expected = new VduInstance();
+        expected.setVduInstanceId("name/da886914-efb2-4917-b335-c8381528d90b");
+        expected.setVduInstanceName("name");
+        VduStatus status = new VduStatus();
+        status.setState(VduStateType.INSTANTIATED);
+        status.setLastAction((new PluginAction("create", "complete", null)));
+        expected.setStatus(status);
+
+        CloudInfo cloudInfo = new CloudInfo();
+        cloudInfo.setCloudSiteId("MTN13");
+        cloudInfo.setTenantId("tenantId");
+        VduModelInfo vduModel = new VduModelInfo();
+        vduModel.setModelCustomizationUUID("blueprintId");
+        vduModel.setTimeoutMinutes(1);
+        VduArtifact artifact = new VduArtifact();
+        artifact.setName("name");
+        artifact.setType(ArtifactType.MAIN_TEMPLATE);
+        byte[] content = new byte[1];
+        artifact.setContent(content);
+        List<VduArtifact> artifacts = new ArrayList<>();
+        artifacts.add(artifact);
+        vduModel.setArtifacts(artifacts);
+        Map<String, byte[]> blueprintFiles = new HashMap<>();
+        blueprintFiles.put(artifact.getName(), artifact.getContent());
+        String instanceName = "stackname";
+        Map<String, Object> inputs = new HashMap<>();
+        boolean rollbackOnFailure = true;
+
+        StubOpenStack.mockOpenStackResponseAccess(wireMockServer, wireMockPort);
+        StubOpenStack.mockOpenStackPostStack_200(wireMockServer, "OpenstackResponse_Stack_Created.json");
+
+        wireMockServer.stubFor(get(urlPathEqualTo("/mockPublicUrl/stacks/stackname/stackId"))
+                .willReturn(aResponse().withHeader("Content-Type", "application/json")
+                        .withBodyFile("OpenstackResponse_StackId.json").withStatus(HttpStatus.SC_OK)));
+
+        VduInstance actual = heatUtils.instantiateVdu(cloudInfo, instanceName, inputs, vduModel, rollbackOnFailure);
+
+        assertThat(actual, sameBeanAs(expected));
+    }
+
+
+    @Test
+    public void queryVduTest() throws Exception {
+        VduInstance expected = new VduInstance();
+        expected.setVduInstanceId("name/da886914-efb2-4917-b335-c8381528d90b");
+        expected.setVduInstanceName("name");
+        VduStatus status = new VduStatus();
+        status.setState(VduStateType.INSTANTIATED);
+        status.setLastAction((new PluginAction("create", "complete", null)));
+        expected.setStatus(status);
+
+        CloudInfo cloudInfo = new CloudInfo();
+        cloudInfo.setCloudSiteId("mtn13");
+        cloudInfo.setTenantId("tenantId");
+        String instanceId = "instanceId";
+
+        StubOpenStack.mockOpenStackResponseAccess(wireMockServer, wireMockPort);
+        StubOpenStack.mockOpenStackPostStack_200(wireMockServer, "OpenstackResponse_Stack_Created.json");
+
+        wireMockServer.stubFor(get(urlPathEqualTo("/mockPublicUrl/stacks/instanceId"))
+                .willReturn(aResponse().withHeader("Content-Type", "application/json")
+                        .withBodyFile("OpenstackResponse_StackId.json").withStatus(HttpStatus.SC_OK)));
+
+        VduInstance actual = heatUtils.queryVdu(cloudInfo, instanceId);
+
+        assertThat(actual, sameBeanAs(expected));
+    }
+
+    @Test
+    public void deleteVduTest() throws Exception {
+        VduInstance expected = new VduInstance();
+        expected.setVduInstanceId("instanceId");
+        expected.setVduInstanceName("instanceId");
+        VduStatus status = new VduStatus();
+        status.setState(VduStateType.DELETED);
+        expected.setStatus(status);
+
+        CloudInfo cloudInfo = new CloudInfo();
+        cloudInfo.setCloudSiteId("mtn13");
+        cloudInfo.setTenantId("tenantId");
+        String instanceId = "instanceId";
+
+        int timeoutInMinutes = 1;
+
+        StubOpenStack.mockOpenStackResponseAccess(wireMockServer, wireMockPort);
+        wireMockServer.stubFor(get(urlPathEqualTo("/mockPublicUrl/stacks/instanceId"))
+                .willReturn(aResponse().withBodyFile("OpenstackResponse_StackId.json").withStatus(HttpStatus.SC_OK)));
+        StubOpenStack.mockOpenStackDelete(wireMockServer, "name/da886914-efb2-4917-b335-c8381528d90b");
+        wireMockServer.stubFor(get(urlPathEqualTo("/mockPublicUrl/stacks/name/da886914-efb2-4917-b335-c8381528d90b"))
+                .willReturn(aResponse().withBodyFile("OpenstackResponse_Stack_DeleteComplete.json")
+                        .withStatus(HttpStatus.SC_OK)));
+
+        VduInstance actual = heatUtils.deleteVdu(cloudInfo, instanceId, timeoutInMinutes);
+
+        assertThat(actual, sameBeanAs(expected));
+    }
+
+    @Test
+    public final void copyBaseOutputsToInputsTest() {
+        Map<String, Object> inputs = new HashMap<>();
+        inputs.put("str1", "str");
+        Map<String, Object> otherStackOutputs = new HashMap<>();
+        otherStackOutputs.put("str", "str");
+        List<String> paramNames = new ArrayList<>();
+        Map<String, String> aliases = new HashMap<>();
+        aliases.put("str", "str");
+        heatUtils.copyBaseOutputsToInputs(inputs, otherStackOutputs, null, aliases);
+        Assert.assertEquals("str", otherStackOutputs.get("str"));
+    }
+
+    @Test
+    public final void getHeatClientSuccessTest() throws MsoException, IOException {
+        CloudSite cloudSite = getCloudSite(getCloudIdentity());
+        StubOpenStack.mockOpenStackResponseAccess(wireMockServer, wireMockPort);
+        Heat heatClient = heatUtils.getHeatClient("MTN13", "TEST-tenant");
+        assertNotNull(heatClient);
+    }
+
+    @Test(expected = MsoOpenstackException.class)
+    public final void getHeatClientOpenStackResponseException404Test() throws MsoException, IOException {
+        CloudSite cloudSite = getCloudSite(getCloudIdentity());
+        // mo mocks setup will cause 404 response from wiremock
+        heatUtils.getHeatClient("MTN13", "TEST-tenant");
+    }
+
+    @Test(expected = MsoAdapterException.class)
+    public final void getHeatClientOpenStackResponseException401Test() throws MsoException, IOException {
+        CloudSite cloudSite = getCloudSite(getCloudIdentity());
+        StubOpenStack.mockOpenStackResponseUnauthorized(wireMockServer, wireMockPort);
+        heatUtils.getHeatClient("MTN13", "TEST-tenant");
+    }
+
+    @Test(expected = MsoOpenstackException.class)
+    public final void getHeatClientOpenStackConnectExceptionTest() throws MsoException, IOException {
+        CloudIdentity identity = getCloudIdentity();
+        identity.setIdentityUrl("http://unreachable");
+        CloudSite cloudSite = getCloudSite(identity);
+        // mo mocks setup will cause 404 response from wiremock
+        heatUtils.getHeatClient("MTN13", "TEST-tenant");
+    }
+
+    @Test
+    public final void createStackSuccessTest() throws MsoException, IOException {
+        CloudSite cloudSite = getCloudSite(getCloudIdentity());
+        StubOpenStack.mockOpenStackResponseAccess(wireMockServer, wireMockPort);
+        StubOpenStack.mockOpenStackPostStack_200(wireMockServer, "OpenstackResponse_Stack_Created.json");
+        StubOpenStack.mockOpenStackGet(wireMockServer, "TEST-stack/stackId");
+        StackInfo stackInfo = heatUtils.createStack(cloudSite.getId(), "CloudOwner", "tenantId", "TEST-stack",
+                "TEST-heat", new HashMap<>(), false, 1, "TEST-env", new HashMap<>(), new HashMap<>());
+        assertNotNull(stackInfo);
+    }
+
+
+
+}
index 3f5402c..1d38bc2 100644 (file)
@@ -2,16 +2,14 @@
  * ============LICENSE_START=======================================================
  * ONAP - SO
  * ================================================================================
- * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Modifications Copyright (c) 2019 Samsung
+ * Copyright (C) 2019 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.
 
 package org.onap.so.openstack.utils;
 
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
-import static com.shazam.shazamcrest.MatcherAssert.assertThat;
-import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs;
-import static org.junit.Assert.assertNotNull;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.times;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import org.apache.http.HttpStatus;
-import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
-import org.onap.so.BaseTest;
-import org.onap.so.StubOpenStack;
-import org.onap.so.adapters.vdu.CloudInfo;
-import org.onap.so.adapters.vdu.PluginAction;
-import org.onap.so.adapters.vdu.VduArtifact;
-import org.onap.so.adapters.vdu.VduArtifact.ArtifactType;
-import org.onap.so.adapters.vdu.VduInstance;
-import org.onap.so.adapters.vdu.VduModelInfo;
-import org.onap.so.adapters.vdu.VduStateType;
-import org.onap.so.adapters.vdu.VduStatus;
-import org.onap.so.db.catalog.beans.CloudIdentity;
-import org.onap.so.db.catalog.beans.CloudSite;
-import org.onap.so.openstack.beans.StackInfo;
-import org.onap.so.openstack.exceptions.MsoAdapterException;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
 import org.onap.so.openstack.exceptions.MsoException;
-import org.onap.so.openstack.exceptions.MsoIOException;
 import org.onap.so.openstack.exceptions.MsoOpenstackException;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.onap.so.openstack.exceptions.MsoStackAlreadyExists;
+import org.springframework.core.env.Environment;
+import com.woorea.openstack.base.client.OpenStackResponseException;
 import com.woorea.openstack.heat.Heat;
+import com.woorea.openstack.heat.StackResource;
+import com.woorea.openstack.heat.StackResource.CreateStack;
+import com.woorea.openstack.heat.StackResource.DeleteStack;
 import com.woorea.openstack.heat.model.CreateStackParam;
+import com.woorea.openstack.heat.model.Resource;
+import com.woorea.openstack.heat.model.Resources;
+import com.woorea.openstack.heat.model.Stack;
 
-public class MsoHeatUtilsTest extends BaseTest {
+@RunWith(MockitoJUnitRunner.class)
+public class MsoHeatUtilsTest extends MsoHeatUtils {
 
-    @Autowired
+    @Rule
+    public ExpectedException exceptionRule = ExpectedException.none();
+
+    @Spy
+    @InjectMocks
     private MsoHeatUtils heatUtils;
 
-    @Test
-    public void instantiateVduTest() throws MsoException, IOException {
-        VduInstance expected = new VduInstance();
-        expected.setVduInstanceId("name/da886914-efb2-4917-b335-c8381528d90b");
-        expected.setVduInstanceName("name");
-        VduStatus status = new VduStatus();
-        status.setState(VduStateType.INSTANTIATED);
-        status.setLastAction((new PluginAction("create", "complete", null)));
-        expected.setStatus(status);
+    @Mock
+    private Heat heatClient;
 
-        CloudInfo cloudInfo = new CloudInfo();
-        cloudInfo.setCloudSiteId("MTN13");
-        cloudInfo.setTenantId("tenantId");
-        VduModelInfo vduModel = new VduModelInfo();
-        vduModel.setModelCustomizationUUID("blueprintId");
-        vduModel.setTimeoutMinutes(1);
-        VduArtifact artifact = new VduArtifact();
-        artifact.setName("name");
-        artifact.setType(ArtifactType.MAIN_TEMPLATE);
-        byte[] content = new byte[1];
-        artifact.setContent(content);
-        List<VduArtifact> artifacts = new ArrayList<>();
-        artifacts.add(artifact);
-        vduModel.setArtifacts(artifacts);
-        Map<String, byte[]> blueprintFiles = new HashMap<>();
-        blueprintFiles.put(artifact.getName(), artifact.getContent());
-        String instanceName = "instanceName";
-        Map<String, Object> inputs = new HashMap<>();
-        boolean rollbackOnFailure = true;
+    @Mock
+    private StackStatusHandler stackStatusHandler;
 
-        StubOpenStack.mockOpenStackResponseAccess(wireMockServer, wireMockPort);
-        StubOpenStack.mockOpenStackPostStack_200(wireMockServer, "OpenstackResponse_Stack_Created.json");
+    @Mock
+    private Environment env;
 
-        wireMockServer.stubFor(get(urlPathEqualTo("/mockPublicUrl/stacks/instanceName/stackId"))
-                .willReturn(aResponse().withHeader("Content-Type", "application/json")
-                        .withBodyFile("OpenstackResponse_StackId.json").withStatus(HttpStatus.SC_OK)));
+    @Mock
+    private StackResource stackResource;
 
-        VduInstance actual = heatUtils.instantiateVdu(cloudInfo, instanceName, inputs, vduModel, rollbackOnFailure);
+    @Mock
+    private NovaClientImpl novaClient;
 
-        assertThat(actual, sameBeanAs(expected));
-    }
+    @Mock
+    private DeleteStack mockDeleteStack;
 
+    @Mock
+    private Resources mockResources;
 
-    @Test
-    public void queryVduTest() throws Exception {
-        VduInstance expected = new VduInstance();
-        expected.setVduInstanceId("name/da886914-efb2-4917-b335-c8381528d90b");
-        expected.setVduInstanceName("name");
-        VduStatus status = new VduStatus();
-        status.setState(VduStateType.INSTANTIATED);
-        status.setLastAction((new PluginAction("create", "complete", null)));
-        expected.setStatus(status);
+    @Mock
+    private CreateStack mockCreateStack;
 
-        CloudInfo cloudInfo = new CloudInfo();
-        cloudInfo.setCloudSiteId("mtn13");
-        cloudInfo.setTenantId("tenantId");
-        String instanceId = "instanceId";
+    private String cloudSiteId = "cloudSiteId";
+    private String tenantId = "tenantId";
 
-        StubOpenStack.mockOpenStackResponseAccess(wireMockServer, wireMockPort);
-        StubOpenStack.mockOpenStackPostStack_200(wireMockServer, "OpenstackResponse_Stack_Created.json");
+    @Before
+    public void setup() {
+        doReturn("15").when(env).getProperty("org.onap.so.adapters.po.pollInterval", "15");
+        doReturn("1").when(env).getProperty("org.onap.so.adapters.po.pollMultiplier", "60");
+    }
+
+    @Test
+    public final void pollStackForStatus_Create_Complete_Test() throws MsoException, IOException {
+        Stack stack = new Stack();
+        stack.setId("id");
+        stack.setStackName("stackName");
+        stack.setStackStatus("CREATE_IN_PROGRESS");
+        stack.setStackStatusReason("Stack Finished");
+
+        Stack latestStack = new Stack();
+        latestStack.setId("id");
+        latestStack.setStackName("stackName");
+        latestStack.setStackStatus("CREATE_COMPLETE");
+        latestStack.setStackStatusReason("Stack Finished");
+        doNothing().when(stackStatusHandler).updateStackStatus(stack);
+        doReturn(latestStack).when(heatUtils).queryHeatStack(isA(Heat.class), eq("stackName/id"));
+        doReturn(heatClient).when(heatUtils).getHeatClient(cloudSiteId, tenantId);
+        Stack actual = heatUtils.pollStackForStatus(1, stack, "CREATE_IN_PROGRESS", cloudSiteId, tenantId);
+        Mockito.verify(stackStatusHandler, times(1)).updateStackStatus(stack);
+        Mockito.verify(heatUtils, times(1)).queryHeatStack(isA(Heat.class), eq("stackName/id"));
+        assertEquals(true, actual != null);
+    }
 
-        wireMockServer.stubFor(get(urlPathEqualTo("/mockPublicUrl/stacks/instanceId"))
-                .willReturn(aResponse().withHeader("Content-Type", "application/json")
-                        .withBodyFile("OpenstackResponse_StackId.json").withStatus(HttpStatus.SC_OK)));
 
-        VduInstance actual = heatUtils.queryVdu(cloudInfo, instanceId);
+    @Test
+    public final void pollStackForStatus_Polling_Exhausted_Test() throws MsoException, IOException {
+        Stack stack = new Stack();
+        stack.setId("id");
+        stack.setStackName("stackName");
+        stack.setStackStatus("CREATE_IN_PROGRESS");
+        stack.setStackStatusReason("Stack Finished");
+        doNothing().when(stackStatusHandler).updateStackStatus(stack);
+        doReturn(stack).when(heatUtils).queryHeatStack(isA(Heat.class), eq("stackName/id"));
+        doReturn(heatClient).when(heatUtils).getHeatClient(cloudSiteId, tenantId);
+        Stack actual = heatUtils.pollStackForStatus(1, stack, "CREATE_IN_PROGRESS", cloudSiteId, tenantId);
+        Mockito.verify(stackStatusHandler, times(1)).updateStackStatus(stack);
+        Mockito.verify(heatUtils, times(1)).queryHeatStack(isA(Heat.class), eq("stackName/id"));
+        assertEquals(true, actual != null);
+    }
 
-        assertThat(actual, sameBeanAs(expected));
+    @Test
+    public final void postProcessStackCreate_CREATE_IN_PROGRESS_Test() throws MsoException, IOException {
+        Stack stack = new Stack();
+        stack.setId("id");
+        stack.setStackName("stackName");
+        stack.setStackStatus("CREATE_IN_PROGRESS");
+        stack.setStackStatusReason("Stack Finished");
+        CreateStackParam createStackParam = new CreateStackParam();
+        createStackParam.setStackName("stackName");
+
+        exceptionRule.expect(StackCreationException.class);
+        exceptionRule.expectMessage("Stack rollback suppressed, stack not deleted");
+        heatUtils.postProcessStackCreate(stack, false, 120, false, cloudSiteId, tenantId, createStackParam);
     }
 
     @Test
-    public void deleteVduTest() throws Exception {
-        VduInstance expected = new VduInstance();
-        expected.setVduInstanceId("instanceId");
-        expected.setVduInstanceName("instanceId");
-        VduStatus status = new VduStatus();
-        status.setState(VduStateType.DELETED);
-        expected.setStatus(status);
+    public final void postProcessStackCreate_Backout_True_Test() throws MsoException, IOException {
+        Stack stack = new Stack();
+        stack.setId("id");
+        stack.setStackName("stackName");
+        stack.setStackStatus("CREATE_IN_PROGRESS");
+        stack.setStackStatusReason("Stack Finished");
+
+        Stack deletedStack = new Stack();
+        deletedStack.setId("id");
+        deletedStack.setStackName("stackName");
+        deletedStack.setStackStatus("DELETE_COMPLETE");
+        deletedStack.setStackStatusReason("Stack Deleted");
+
+        CreateStackParam createStackParam = new CreateStackParam();
+        createStackParam.setStackName("stackName");
+        doReturn(deletedStack).when(heatUtils).handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
+        exceptionRule.expect(StackCreationException.class);
+        exceptionRule.expectMessage(
+                "Stack Creation Failed Openstack Status: CREATE_IN_PROGRESS Status Reason: Stack Finished , Rollback of Stack Creation completed with status: DELETE_COMPLETE Status Reason: Stack Deleted");
+        heatUtils.postProcessStackCreate(stack, true, 120, false, cloudSiteId, tenantId, createStackParam);
+        Mockito.verify(heatUtils, times(1)).handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
+    }
 
-        CloudInfo cloudInfo = new CloudInfo();
-        cloudInfo.setCloudSiteId("mtn13");
-        cloudInfo.setTenantId("tenantId");
-        String instanceId = "instanceId";
+    @Test
+    public final void postProcessStackCreate_Keypair_True_Test() throws MsoException, IOException {
+        Stack stack = new Stack();
+        stack.setId("id");
+        stack.setStackName("stackName");
+        stack.setStackStatus("CREATE_IN_PROGRESS");
+        stack.setStackStatusReason(
+                "Resource CREATE failed: Conflict: resources.my_keypair: Key pair 'hst3bbfnm0011vm001' already exists. (HTTP 409) (Request-ID: req-941b0af6-63ae-4d6a-afbc-90b728bacf82");
+
+        Stack createdStack = new Stack();
+        createdStack.setId("id");
+        createdStack.setStackName("stackName");
+        createdStack.setStackStatus("CREATE_COMPLETE");
+        createdStack.setStackStatusReason("Stack Created");
+
+        CreateStackParam createStackParam = new CreateStackParam();
+        createStackParam.setStackName("stackName");
+        doReturn(createdStack).when(heatUtils).handleKeyPairConflict(cloudSiteId, tenantId, createStackParam, 120, true,
+                stack);
+        heatUtils.postProcessStackCreate(stack, true, 120, true, cloudSiteId, tenantId, createStackParam);
+        Mockito.verify(heatUtils, times(1)).handleKeyPairConflict(cloudSiteId, tenantId, createStackParam, 120, true,
+                stack);
+    }
 
-        int timeoutInMinutes = 1;
+    @Test
+    public final void handleUnknownCreateStackFailure_Test() throws MsoException, IOException {
+
+        Stack stack = new Stack();
+        stack.setId("id");
+        stack.setStackName("stackName");
+        stack.setStackStatus("CREATE_FAILED");
+        stack.setStackStatusReason(
+                "Resource CREATE failed: Conflict: resources.my_keypair: Key pair 'hst3bbfnm0011vm001' already exists. (HTTP 409) (Request-ID: req-941b0af6-63ae-4d6a-afbc-90b728bacf82");
+
+        Stack deletedStack = new Stack();
+        deletedStack.setId("id");
+        deletedStack.setStackName("stackName");
+        deletedStack.setStackStatus("DELETE_COMPLETE");
+        deletedStack.setStackStatusReason("Stack Deleted");
+
+        CreateStackParam createStackParam = new CreateStackParam();
+        createStackParam.setStackName("stackName");
+        doReturn(heatClient).when(heatUtils).getHeatClient(cloudSiteId, tenantId);
+        doNothing().when(heatUtils).postProcessStackDelete(deletedStack);
+        doReturn(null).when(heatUtils).executeAndRecordOpenstackRequest(mockDeleteStack);
+        doReturn(stackResource).when(heatClient).getStacks();
+        doReturn(mockDeleteStack).when(stackResource).deleteByName("stackName/id");
+        doReturn(deletedStack).when(heatUtils).pollStackForStatus(120, stack, "DELETE_IN_PROGRESS", cloudSiteId,
+                tenantId);
+
+        heatUtils.handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
+        Mockito.verify(heatUtils, times(1)).executeAndRecordOpenstackRequest(mockDeleteStack);
+        Mockito.verify(heatUtils, times(1)).pollStackForStatus(120, stack, "DELETE_IN_PROGRESS", cloudSiteId, tenantId);
+        Mockito.verify(heatUtils, times(1)).postProcessStackDelete(deletedStack);
+    }
 
-        StubOpenStack.mockOpenStackResponseAccess(wireMockServer, wireMockPort);
-        wireMockServer.stubFor(get(urlPathEqualTo("/mockPublicUrl/stacks/instanceId"))
-                .willReturn(aResponse().withBodyFile("OpenstackResponse_StackId.json").withStatus(HttpStatus.SC_OK)));
-        StubOpenStack.mockOpenStackDelete(wireMockServer, "name/da886914-efb2-4917-b335-c8381528d90b");
-        wireMockServer.stubFor(get(urlPathEqualTo("/mockPublicUrl/stacks/name/da886914-efb2-4917-b335-c8381528d90b"))
-                .willReturn(aResponse().withBodyFile("OpenstackResponse_Stack_DeleteComplete.json")
-                        .withStatus(HttpStatus.SC_OK)));
 
-        VduInstance actual = heatUtils.deleteVdu(cloudInfo, instanceId, timeoutInMinutes);
+    @Test
+    public final void handleUnknownCreateStackFailure_Null_Stack_Test() throws MsoException, IOException {
+        Stack stack = null;
+        exceptionRule.expect(StackCreationException.class);
+        exceptionRule.expectMessage("Cannot Find Stack Name or Id");
+        heatUtils.handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
+    }
 
-        assertThat(actual, sameBeanAs(expected));
+    @Test
+    public final void postProcessStackDelete_Stack_Test() throws MsoException, IOException {
+        Stack deletedStack = new Stack();
+        deletedStack.setId("id");
+        deletedStack.setStackName("stackName");
+        deletedStack.setStackStatus("DELETE_FAILED");
+        deletedStack.setStackStatusReason("Stack DID NOT DELETE");
+        exceptionRule.expect(StackRollbackException.class);
+        exceptionRule.expectMessage(
+                "Stack Deletion completed with status: DELETE_FAILED Status Reason: Stack DID NOT DELETE");
+        heatUtils.postProcessStackDelete(deletedStack);
     }
 
     @Test
-    public final void requestToStringBuilderTest() {
-        CreateStackParam param = new CreateStackParam();
-        param.setDisableRollback(false);
-        param.setEnvironment("environment");
-        param.setFiles(new HashMap<String, Object>());
-        param.setParameters(new HashMap<>());
-        param.setStackName("stackName");
-        param.setTemplate("template");
-        param.setTemplateUrl("http://templateUrl");
-        param.setTimeoutMinutes(1);
+    public final void postProcessStackDelete__Null_Stack_Test() throws MsoException, IOException {
+        Stack stack = null;
+        exceptionRule.expect(StackRollbackException.class);
+        exceptionRule.expectMessage("Cannot Find Stack Name or Id");
+        heatUtils.postProcessStackDelete(stack);
+    }
 
-        StringBuilder stringBuilder = heatUtils.requestToStringBuilder(param);
+    @Test
+    public final void isKeyPairFailure_Test() throws MsoException, IOException {
+        boolean actual = heatUtils.isKeyPairFailure(
+                "Exception during create VF 0 : Stack error (CREATE_FAILED): Resource CREATE failed: Conflict: resources.bfnm_my_keypair: Key pair 'hst3bbfnm0011vm001' already exists. (HTTP 409) (Request-ID:req-941b0af6-63ae-4d6a-afbc-90b728bacf82) - stack successfully deleted'rolledBack='true'");
+        assertEquals(true, actual);
+    }
 
-        Assert.assertTrue(stringBuilder.toString().contains("StackName:"));
+    @Test
+    public final void handleKeyPairConflict_Test() throws MsoException, IOException, NovaClientException {
+        Stack stack = new Stack();
+        stack.setId("id");
+        stack.setStackName("stackName");
+        stack.setStackStatus("CREATE_FAILED");
+        stack.setStackStatusReason(
+                "Resource CREATE failed: Conflict: resources.my_keypair: Key pair 'hst3bbfnm0011vm001' already exists. (HTTP 409) (Request-ID: req-941b0af6-63ae-4d6a-afbc-90b728bacf82");
+
+        Stack createdStack = new Stack();
+        createdStack.setId("id");
+        createdStack.setStackName("stackName");
+        createdStack.setStackStatus("CREATE_COMPLETE");
+        createdStack.setStackStatusReason("Stack Created");
+
+
+
+        List<Resource> resources = new ArrayList<>();
+        Resource resource = new Resource();
+        resource.setName("KeypairName");
+        resource.setPhysicalResourceId("KeypairName");
+        resource.setType("OS::Nova::KeyPair");
+        resources.add(resource);
+
+        CreateStackParam createStackParam = new CreateStackParam();
+        createStackParam.setStackName("stackName");
+
+        doReturn(resources).when(mockResources).getList();
+        doReturn(mockResources).when(heatUtils).queryStackResources(cloudSiteId, tenantId, "stackName", 2);
+        doNothing().when(novaClient).deleteKeyPair(cloudSiteId, tenantId, "KeypairName");
+        doReturn(null).when(heatUtils).handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
+        doReturn(createdStack).when(heatUtils).createStack(createStackParam, cloudSiteId, tenantId);
+        doReturn(createdStack).when(heatUtils).processCreateStack(cloudSiteId, tenantId, 120, true, createdStack,
+                createStackParam, false);
+
+        heatUtils.handleKeyPairConflict(cloudSiteId, tenantId, createStackParam, 120, true, stack);
+        Mockito.verify(heatUtils, times(1)).queryStackResources(cloudSiteId, tenantId, "stackName", 2);
+        Mockito.verify(novaClient, times(1)).deleteKeyPair(cloudSiteId, tenantId, "KeypairName");
+        Mockito.verify(heatUtils, times(1)).handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
+        Mockito.verify(heatUtils, times(1)).createStack(createStackParam, cloudSiteId, tenantId);
+        Mockito.verify(heatUtils, times(1)).processCreateStack(cloudSiteId, tenantId, 120, true, createdStack,
+                createStackParam, false);
     }
 
     @Test
-    public final void copyBaseOutputsToInputsTest() {
-        Map<String, Object> inputs = new HashMap<>();
-        inputs.put("str1", "str");
-        Map<String, Object> otherStackOutputs = new HashMap<>();
-        otherStackOutputs.put("str", "str");
-        List<String> paramNames = new ArrayList<>();
-        Map<String, String> aliases = new HashMap<>();
-        aliases.put("str", "str");
-        heatUtils.copyBaseOutputsToInputs(inputs, otherStackOutputs, null, aliases);
-        Assert.assertEquals("str", otherStackOutputs.get("str"));
+    public final void processCreateStack_Test() throws MsoException, IOException, NovaClientException {
+        Stack stack = new Stack();
+        stack.setId("id");
+        stack.setStackName("stackName");
+        stack.setStackStatus("CREATE_FAILED");
+        stack.setStackStatusReason(
+                "Resource CREATE failed: Conflict: resources.my_keypair: Key pair 'hst3bbfnm0011vm001' already exists. (HTTP 409) (Request-ID: req-941b0af6-63ae-4d6a-afbc-90b728bacf82");
+
+        Stack createdStack = new Stack();
+        createdStack.setId("id");
+        createdStack.setStackName("stackName");
+        createdStack.setStackStatus("CREATE_COMPLETE");
+        createdStack.setStackStatusReason("Stack Created");
+
+
+        CreateStackParam createStackParam = new CreateStackParam();
+        createStackParam.setStackName("stackName");
+
+        doReturn(createdStack).when(heatUtils).pollStackForStatus(120, stack, "CREATE_IN_PROGRESS", cloudSiteId,
+                tenantId);
+        doReturn(createdStack).when(heatUtils).postProcessStackCreate(createdStack, true, 120, true, cloudSiteId,
+                tenantId, createStackParam);
+
+        heatUtils.processCreateStack(cloudSiteId, tenantId, 120, true, stack, createStackParam, true);
+        Mockito.verify(heatUtils, times(1)).pollStackForStatus(120, stack, "CREATE_IN_PROGRESS", cloudSiteId, tenantId);
+        Mockito.verify(heatUtils, times(1)).postProcessStackCreate(createdStack, true, 120, true, cloudSiteId, tenantId,
+                createStackParam);
     }
 
     @Test
-    public final void getHeatClientSuccessTest() throws MsoException, IOException {
-        CloudSite cloudSite = getCloudSite(getCloudIdentity());
-        StubOpenStack.mockOpenStackResponseAccess(wireMockServer, wireMockPort);
-        Heat heatClient = heatUtils.getHeatClient(cloudSite, "TEST-tenant");
-        assertNotNull(heatClient);
+    public final void processCreateStack_Exception_Backout_Test()
+            throws MsoException, IOException, NovaClientException {
+        Stack stack = new Stack();
+        stack.setId("id");
+        stack.setStackName("stackName");
+        stack.setStackStatus("CREATE_FAILED");
+        stack.setStackStatusReason(
+                "Resource CREATE failed: Conflict: resources.my_keypair: Key pair 'hst3bbfnm0011vm001' already exists. (HTTP 409) (Request-ID: req-941b0af6-63ae-4d6a-afbc-90b728bacf82");
+
+        Stack deletedStack = new Stack();
+        deletedStack.setId("id");
+        deletedStack.setStackName("stackName");
+        deletedStack.setStackStatus("DELETE_COMPLETE");
+        deletedStack.setStackStatusReason("Stack Deleted");
+
+        CreateStackParam createStackParam = new CreateStackParam();
+        createStackParam.setStackName("stackName");
+
+        doThrow(new StackCreationException("Error")).when(heatUtils).pollStackForStatus(120, stack,
+                "CREATE_IN_PROGRESS", cloudSiteId, tenantId);
+        doReturn(deletedStack).when(heatUtils).handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
+        exceptionRule.expect(MsoException.class);
+        exceptionRule.expectMessage("Error");
+        heatUtils.processCreateStack(cloudSiteId, tenantId, 120, true, stack, createStackParam, true);
+        Mockito.verify(heatUtils, times(1)).pollStackForStatus(120, stack, "CREATE_IN_PROGRESS", cloudSiteId, tenantId);
+        Mockito.verify(heatUtils, times(1)).handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
     }
 
-    @Test(expected = MsoOpenstackException.class)
-    public final void getHeatClientOpenStackResponseException404Test() throws MsoException, IOException {
-        CloudSite cloudSite = getCloudSite(getCloudIdentity());
-        // mo mocks setup will cause 404 response from wiremock
-        heatUtils.getHeatClient(cloudSite, "TEST-tenant");
+
+    @Test
+    public final void createStack_Test() throws MsoException, IOException, NovaClientException {
+        CreateStackParam createStackParam = new CreateStackParam();
+        createStackParam.setStackName("stackName");
+
+        doReturn(heatClient).when(heatUtils).getHeatClient(cloudSiteId, tenantId);
+        doReturn(stackResource).when(heatClient).getStacks();
+        doReturn(mockCreateStack).when(stackResource).create(createStackParam);
+
+        doReturn(null).when(heatUtils).executeAndRecordOpenstackRequest(mockCreateStack);
+
+        heatUtils.createStack(createStackParam, cloudSiteId, tenantId);
+        Mockito.verify(stackResource, times(1)).create(createStackParam);
+        Mockito.verify(heatUtils, times(1)).saveStackRequest(eq(mockCreateStack), isNull(), eq("stackName"));
+        Mockito.verify(heatClient, times(1)).getStacks();
+        Mockito.verify(stackResource, times(1)).create(createStackParam);
     }
 
-    @Test(expected = MsoAdapterException.class)
-    public final void getHeatClientOpenStackResponseException401Test() throws MsoException, IOException {
-        CloudSite cloudSite = getCloudSite(getCloudIdentity());
-        StubOpenStack.mockOpenStackResponseUnauthorized(wireMockServer, wireMockPort);
-        heatUtils.getHeatClient(cloudSite, "TEST-tenant");
+    @Test
+    public final void createStack_Error_Test() throws MsoException, IOException, NovaClientException {
+        CreateStackParam createStackParam = new CreateStackParam();
+        createStackParam.setStackName("stackName");
+
+        doReturn(heatClient).when(heatUtils).getHeatClient(cloudSiteId, tenantId);
+        doReturn(stackResource).when(heatClient).getStacks();
+        doReturn(mockCreateStack).when(stackResource).create(createStackParam);
+
+        doThrow(new OpenStackResponseException("Unknown Error", 500)).when(heatUtils)
+                .executeAndRecordOpenstackRequest(mockCreateStack);
+        exceptionRule.expect(MsoOpenstackException.class);
+        exceptionRule.expectMessage("Unknown Error");
+        heatUtils.createStack(createStackParam, cloudSiteId, tenantId);
+        Mockito.verify(stackResource, times(1)).create(createStackParam);
+        Mockito.verify(heatUtils, times(1)).saveStackRequest(eq(mockCreateStack), isNull(), eq("stackName"));
+        Mockito.verify(heatClient, times(1)).getStacks();
+        Mockito.verify(stackResource, times(1)).create(createStackParam);
     }
 
-    @Test(expected = MsoIOException.class)
-    public final void getHeatClientOpenStackConnectExceptionTest() throws MsoException, IOException {
-        CloudIdentity identity = getCloudIdentity();
-        identity.setIdentityUrl("http://unreachable");
-        CloudSite cloudSite = getCloudSite(identity);
-        // mo mocks setup will cause 404 response from wiremock
-        heatUtils.getHeatClient(cloudSite, "TEST-tenant");
+    @Test
+    public final void createStack_Error_404_Test() throws MsoException, IOException, NovaClientException {
+        CreateStackParam createStackParam = new CreateStackParam();
+        createStackParam.setStackName("stackName");
+
+        doReturn(heatClient).when(heatUtils).getHeatClient(cloudSiteId, tenantId);
+        doReturn(stackResource).when(heatClient).getStacks();
+        doReturn(mockCreateStack).when(stackResource).create(createStackParam);
+
+        doThrow(new OpenStackResponseException("Not Found", 409)).when(heatUtils)
+                .executeAndRecordOpenstackRequest(mockCreateStack);
+        exceptionRule.expect(MsoStackAlreadyExists.class);
+        exceptionRule.expectMessage("Stack stackName already exists in Tenant tenantId in Cloud cloudSiteId");
+        heatUtils.createStack(createStackParam, cloudSiteId, tenantId);
+        Mockito.verify(stackResource, times(1)).create(createStackParam);
+        Mockito.verify(heatUtils, times(1)).saveStackRequest(eq(mockCreateStack), isNull(), eq("stackName"));
+        Mockito.verify(heatClient, times(1)).getStacks();
+        Mockito.verify(stackResource, times(1)).create(createStackParam);
     }
 
     @Test
-    public final void createStackSuccessTest() throws MsoException, IOException {
-        CloudSite cloudSite = getCloudSite(getCloudIdentity());
-        StubOpenStack.mockOpenStackResponseAccess(wireMockServer, wireMockPort);
-        StubOpenStack.mockOpenStackPostStack_200(wireMockServer, "OpenstackResponse_Stack_Created.json");
-        StubOpenStack.mockOpenStackGet(wireMockServer, "TEST-stack/stackId");
-        StackInfo stackInfo = heatUtils.createStack(cloudSite.getId(), "CloudOwner", "tenantId", "TEST-stack", null,
-                "TEST-heat", new HashMap<>(), false, 1, "TEST-env", new HashMap<>(), new HashMap<>(), false);
-        assertNotNull(stackInfo);
+    public final void processCreateStack_Exception_No_Backout_Test()
+            throws MsoException, IOException, NovaClientException {
+        Stack stack = new Stack();
+        stack.setId("id");
+        stack.setStackName("stackName");
+        stack.setStackStatus("CREATE_FAILED");
+        stack.setStackStatusReason(
+                "Resource CREATE failed: Conflict: resources.my_keypair: Key pair 'hst3bbfnm0011vm001' already exists. (HTTP 409) (Request-ID: req-941b0af6-63ae-4d6a-afbc-90b728bacf82");
+
+        Stack deletedStack = new Stack();
+        deletedStack.setId("id");
+        deletedStack.setStackName("stackName");
+        deletedStack.setStackStatus("DELETE_COMPLETE");
+        deletedStack.setStackStatusReason("Stack Deleted");
+
+        CreateStackParam createStackParam = new CreateStackParam();
+        createStackParam.setStackName("stackName");
+
+        doThrow(new StackCreationException("Error")).when(heatUtils).pollStackForStatus(120, stack,
+                "CREATE_IN_PROGRESS", cloudSiteId, tenantId);
+
+        exceptionRule.expect(MsoException.class);
+        exceptionRule.expectMessage("Error");
+        heatUtils.processCreateStack(cloudSiteId, tenantId, 120, false, stack, createStackParam, true);
+        Mockito.verify(heatUtils, times(1)).pollStackForStatus(120, stack, "CREATE_IN_PROGRESS", cloudSiteId, tenantId);
+        Mockito.verify(heatUtils, times(0)).handleUnknownCreateStackFailure(stack, 120, cloudSiteId, tenantId);
     }
+
 }
index 8951f8a..acd42dd 100644 (file)
@@ -22,10 +22,8 @@ package org.onap.so.openstack.utils;
 
 import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs;
 import static org.junit.Assert.assertThat;
-import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.isA;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
 import java.io.File;
 import java.io.IOException;
 import java.util.HashMap;
@@ -98,7 +96,7 @@ public class MsoHeatUtilsWithUpdateTest extends TestDataSetup {
         expectedStackInfo.setCanonicalName("stackName/id");
 
         doReturn(Optional.of(cloudSite)).when(cloudConfig).getCloudSite(isA(String.class));
-        doReturn(heatClient).when(heatUtils).getHeatClient(isA(CloudSite.class), isA(String.class));
+        doReturn(heatClient).when(heatUtils).getHeatClient(isA(String.class), isA(String.class));
         doReturn(null).when(heatUtils).executeAndRecordOpenstackRequest(isA(OpenStackRequest.class));
         doReturn("0").when(environment).getProperty(isA(String.class), isA(String.class));
         doReturn(updateStack).when(heatUtils).queryHeatStack(isA(Heat.class), isA(String.class));
@@ -123,7 +121,7 @@ public class MsoHeatUtilsWithUpdateTest extends TestDataSetup {
         expectedStackInfo.setCanonicalName("stackName/id");
 
         doReturn(Optional.of(cloudSite)).when(cloudConfig).getCloudSite(isA(String.class));
-        doReturn(heatClient).when(heatUtils).getHeatClient(isA(CloudSite.class), isA(String.class));
+        doReturn(heatClient).when(heatUtils).getHeatClient(isA(String.class), isA(String.class));
 
         doReturn(null).when(heatUtils).executeAndRecordOpenstackRequest(isA(OpenStackRequest.class));
         doReturn("0").when(environment).getProperty(isA(String.class), isA(String.class));
@@ -150,7 +148,7 @@ public class MsoHeatUtilsWithUpdateTest extends TestDataSetup {
         expectedStackInfo.setCanonicalName("stackName/id");
 
         doReturn(Optional.of(cloudSite)).when(cloudConfig).getCloudSite(isA(String.class));
-        doReturn(heatClient).when(heatUtils).getHeatClient(isA(CloudSite.class), isA(String.class));
+        doReturn(heatClient).when(heatUtils).getHeatClient(isA(String.class), isA(String.class));
         doReturn(null).when(heatUtils).executeAndRecordOpenstackRequest(isA(OpenStackRequest.class));
         doReturn("0").when(environment).getProperty(isA(String.class), isA(String.class));
         doReturn(updateStack).when(heatUtils).queryHeatStack(isA(Heat.class), isA(String.class));
index 477acad..7eae6d1 100644 (file)
@@ -2,7 +2,7 @@
        "stack": {
                "description": null,
                "links": null,
-               "stack_status_reason": null,
+               "stack_status_reason": "Stack Created",
                "stack_name": "stackname",
                "updated_time": null,
                "creation_time": null,
index 431870b..afe9d71 100644 (file)
 
 package org.onap.so.openstack.beans;
 
-
-
+import java.io.Serializable;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlType;
 
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "", propOrder = {"prefix", "nextHop"})
-public class HostRoute {
+public class HostRoute implements Serializable {
 
+    private static final long serialVersionUID = 2468793257174064133L;
     private String prefix;
     private String nextHop;
 
index 57d31bf..f354e6c 100644 (file)
@@ -71,7 +71,7 @@ public class AuditStackService {
         ClientRequestInterceptor interceptor = createClientRequestInterceptor();
         ExternalTaskClient client = ExternalTaskClient.create()
                 .baseUrl(env.getRequiredProperty("mso.workflow.endpoint")).maxTasks(1).addInterceptor(interceptor)
-                .asyncResponseTimeout(120000).backoffStrategy(new ExponentialBackoffStrategy(10000, 2, 120000)).build();
+                .asyncResponseTimeout(120000).backoffStrategy(new ExponentialBackoffStrategy(0, 0, 0)).build();
         return client;
     }
 
index bac41a1..352cd7b 100644 (file)
@@ -64,9 +64,9 @@ import org.onap.so.db.catalog.data.repository.VFModuleCustomizationRepository;
 import org.onap.so.db.catalog.data.repository.VnfResourceRepository;
 import org.onap.so.db.catalog.utils.MavenLikeVersioning;
 import org.onap.so.entity.MsoRequest;
-import org.onap.so.logger.ErrorCode;
 import org.onap.so.heatbridge.HeatBridgeApi;
 import org.onap.so.heatbridge.HeatBridgeImpl;
+import org.onap.so.logger.ErrorCode;
 import org.onap.so.logger.MessageEnum;
 import org.onap.so.openstack.beans.HeatStatus;
 import org.onap.so.openstack.beans.StackInfo;
@@ -79,10 +79,6 @@ import org.onap.so.openstack.exceptions.MsoHeatNotFoundException;
 import org.onap.so.openstack.utils.MsoHeatEnvironmentEntry;
 import org.onap.so.openstack.utils.MsoHeatUtils;
 import org.onap.so.openstack.utils.MsoHeatUtilsWithUpdate;
-import org.openstack4j.model.compute.Flavor;
-import org.openstack4j.model.compute.Image;
-import org.openstack4j.model.compute.Server;
-import org.openstack4j.model.heat.Resource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -92,6 +88,10 @@ import org.springframework.transaction.annotation.Transactional;
 import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import org.openstack4j.model.compute.Flavor;
+import org.openstack4j.model.compute.Image;
+import org.openstack4j.model.compute.Server;
+import org.openstack4j.model.heat.Resource;
 
 @WebService(serviceName = "VnfAdapter", endpointInterface = "org.onap.so.adapters.vnf.MsoVnfAdapter",
         targetNamespace = "http://org.onap.so/vnf")
@@ -107,6 +107,7 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
 
     private static final Logger logger = LoggerFactory.getLogger(MsoVnfAdapterImpl.class);
 
+
     private static final String VNF_ADAPTER_SERVICE_NAME = "MSO-BPMN:MSO-VnfAdapter.";
     private static final String CHECK_REQD_PARAMS = "org.onap.so.adapters.vnf.checkRequiredParameters";
     private static final String ADD_GET_FILES_ON_VOLUME_REQ = "org.onap.so.adapters.vnf.addGetFilesOnVolumeReq";
@@ -116,6 +117,8 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
             "org.onap.so.adapters.vnf.fail_requests_on_valet_failure";
     private static final String OPENSTACK = "OpenStack";
 
+
+
     @Autowired
     private VFModuleCustomizationRepository vfModuleCustomRepo;
 
@@ -606,7 +609,7 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
             requestTypeString = requestTypeString.substring(1);
         }
 
-        // 1607 - let's parse out the request type we're being sent
+        // let's parse out the request type we're being sent
         boolean isBaseRequest = false;
         boolean isVolumeRequest = false;
         if (requestTypeString.startsWith("VOLUME")) {
@@ -615,8 +618,6 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
 
         logger.debug("requestTypeString = " + requestTypeString + ", nestedStackId = " + nestedStackId
                 + ", nestedBaseStackId = " + nestedBaseStackId);
-        // Will capture execution time for metrics
-        long startTime = System.currentTimeMillis();
 
         // Build a default rollback object (no actions performed)
         VnfRollback vfRollback = new VnfRollback();
@@ -636,7 +637,6 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
         }
 
         StackInfo heatStack = null;
-        long subStartTime1 = System.currentTimeMillis();
         try {
             heatStack = heat.queryStack(cloudSiteId, cloudOwner, tenantId, vfModuleName);
         } catch (MsoException me) {
@@ -651,7 +651,7 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
             me.addContext("CreateVFModule");
             throw new VnfException(me);
         }
-        // New with 1607 - more precise handling/messaging if the stack already exists
+        // more precise handling/messaging if the stack already exists
         if (heatStack != null && heatStack.getStatus() != HeatStatus.NOTFOUND) {
             // INIT, CREATED, NOTFOUND, FAILED, BUILDING, DELETING, UNKNOWN, UPDATING, UPDATED
             HeatStatus status = heatStack.getStatus();
@@ -716,7 +716,7 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
 
         // handle a nestedStackId if sent- this one would be for the volume - so applies to both Vf and Vnf
         StackInfo nestedHeatStack = null;
-        long subStartTime2 = System.currentTimeMillis();
+
         Map<String, Object> nestedVolumeOutputs = null;
         if (nestedStackId != null) {
             try {
@@ -751,7 +751,6 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
 
         // handle a nestedBaseStackId if sent- this is the stack ID of the base. Should be null for VNF requests
         StackInfo nestedBaseHeatStack = null;
-        long subStartTime3 = System.currentTimeMillis();
         Map<String, Object> baseStackOutputs = null;
         if (nestedBaseStackId != null) {
             try {
@@ -785,25 +784,19 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
             }
         }
 
-        // Ready to deploy the new VNF
-
-
-
         try {
             // Retrieve the VF
             VfModule vf = null;
             VnfResource vnfResource = null;
             VfModuleCustomization vfmc = null;
-            logger.debug("version: {}", vfVersion);
             if (useMCUuid) {
-                // 1707 - db refactoring
                 vfmc = vfModuleCustomRepo.findFirstByModelCustomizationUUIDOrderByCreatedDesc(mcu);
                 if (vfmc != null)
                     vf = vfmc.getVfModule();
                 else
                     vf = null;
 
-                // 1702 - this will be the new way going forward. We find the vf by mcu - otherwise, code is the same.
+                // this will be the new way going forward. We find the vf by mcu - otherwise, code is the same.
                 if (vf == null) {
                     logger.debug("Unable to find vfModuleCust with modelCustomizationUuid={}", mcu);
                     String error =
@@ -846,7 +839,7 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
             }
             // By here - we have either a vf or vnfResource
 
-            // 1607 - Add version check
+            // Add version check
             // First - see if it's in the VnfResource record
             // if we have a vf Module - then we have to query to get the VnfResource record.
             if (!oldWay && vf.getVnfResources() != null) {
@@ -894,7 +887,7 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
                             equalToMax = aicV.isTheSameVersion(maxVersionVnf);
                         } catch (Exception e) {
                             logger.debug(
-                                    "An exception occurred while trying to test AIC Version {} - will default to not check",
+                                    "An exception occurred while trying to test Cloud Version {} - will default to not check",
                                     e.getMessage(), e);
                             doNotTest = true;
                         }
@@ -917,20 +910,13 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
                                 throw new VnfException(error, MsoExceptionCategory.USERDATA);
                             }
                         } else {
-                            logger.debug("bypassing testing AIC version...");
+                            logger.debug("bypassing testing Cloud version...");
                         }
                     } // let this error out downstream to avoid introducing uncertainty at this stage
                 } else {
                     logger.debug("cloudConfig is NULL - cannot check cloud site version");
                 }
-            } else {
-                logger.debug(
-                        "AIC Version not set in VNF_Resource - this is expected thru 1607 - do not error here - not checked"
-                                + ".");
             }
-            // End Version check 1607
-
-
 
             // By the time we get here - heatTemplateId and heatEnvtId should be populated (or null)
             HeatTemplate heatTemplate = null;
@@ -994,7 +980,7 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
                 nestedTemplatesChecked = null;
             }
 
-            // 1510 - Also add the files: for any get_files associated with this vnf_resource_id
+            // Also add the files: for any get_files associated with this vnf_resource_id
             // *if* there are any
             List<HeatFiles> heatFiles = null;
 
@@ -1015,11 +1001,9 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
 
             if (!isVolumeRequest || addGetFilesOnVolumeReq) {
                 if (oldWay) {
-                    logger.debug(
-                            "In MsoVnfAdapterImpl createVfModule, this should not happen - old way is gamma only - no heat "
-                                    + "files!");
+                    logger.debug("In MsoVnfAdapterImpl createVfModule, this should not happen, no heat files!");
                 } else {
-                    // 1607 - now use VF_MODULE_TO_HEAT_FILES table
+                    // now use VF_MODULE_TO_HEAT_FILES table
                     logger.debug(
                             "In MsoVnfAdapterImpl createVfModule, about to call db.getHeatFilesForVfModule avec vfModuleId="
                                     + vf.getModelUUID());
@@ -1046,9 +1030,9 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
             String missingParams = null;
             List<String> paramList = new ArrayList<>();
 
-            // New for 1510 - consult the PARAM_ALIAS field to see if we've been
+            // consult the PARAM_ALIAS field to see if we've been
             // supplied an alias. Only check if we don't find it initially.
-            // Also new in 1510 - don't flag missing parameters if there's an environment - because they might be there.
+            // don't flag missing parameters if there's an environment - because they might be there.
             // And also new - add parameter to turn off checking all together if we find we're blocking orders we
             // shouldn't
             boolean checkRequiredParameters = true;
@@ -1063,7 +1047,6 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
                 // No problem - default is true
                 logger.debug("An exception occured trying to get property {}", MsoVnfAdapterImpl.CHECK_REQD_PARAMS, e);
             }
-            // 1604 - Add enhanced environment & parameter checking
             // Part 1: parse envt entries to see if reqd parameter is there (before used a simple grep
             // Part 2: only submit to openstack the parameters in the envt that are in the heat template
             // Note this also removes any comments
@@ -1071,7 +1054,6 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
             if (heatEnvironment != null && heatEnvironment.getEnvironment() != null
                     && heatEnvironment.getEnvironment().contains("parameters:")) {
 
-                logger.debug("Enhanced environment checking enabled - 1604");
                 StringBuilder sb = new StringBuilder(heatEnvironment.getEnvironment());
 
                 mhee = new MsoHeatEnvironmentEntry(sb);
@@ -1089,10 +1071,9 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
             } else {
                 logger.debug("NO ENVIRONMENT for this entry");
             }
-            // New with 1707 - all variables converted to their native object types
+            // all variables converted to their native object types
             Map<String, Object> goldenInputs = null;
 
-            logger.debug("Now handle the inputs....first convert");
             ArrayList<String> parameterNames = new ArrayList<>();
             HashMap<String, String> aliasToParam = new HashMap<>();
             StringBuilder sb = new StringBuilder("\nTemplate Parameters:\n");
@@ -1193,31 +1174,21 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
             // Have the tenant. Now deploy the stack itself
             // Ignore MsoTenantNotFound and MsoStackAlreadyExists exceptions
             // because we already checked for those.
-            long createStackStarttime = System.currentTimeMillis();
             try {
-                // heatStack = heat.createStack(cloudSiteId, tenantId, vnfName, template, inputs, true,
-                // heatTemplate.getTimeoutMinutes());
                 if (backout == null) {
                     backout = true;
                 }
                 if (heat != null) {
-                    logger.debug("heat is not null!!");
 
                     heatStack = heat.createStack(cloudSiteId, cloudOwner, tenantId, vfModuleName, null, template,
                             goldenInputs, true, heatTemplate.getTimeoutMinutes(), newEnvironmentString,
                             nestedTemplatesChecked, heatFilesObjects, backout.booleanValue());
                 } else {
-                    logger.debug("heat is null!");
                     throw new MsoHeatNotFoundException();
                 }
             } catch (MsoException me) {
                 me.addContext("CreateVFModule");
-                String error = "Create VF Module " + vfModuleType + " in " + cloudOwner + "/" + cloudSiteId + "/"
-                        + tenantId + ": " + me;
-                logger.error("{} {} {} {} {} {} {} {}", MessageEnum.RA_CREATE_VNF_ERR.toString(), vfModuleType,
-                        cloudOwner, cloudSiteId, tenantId, OPENSTACK, ErrorCode.DataError.getValue(),
-                        "MsoException - createStack", me);
-                logger.debug(error);
+                logger.error("Error creating Stack", me);
                 if (isValetEnabled && sendResponseToValet) {
                     logger.debug("valet is enabled, the orchestration failed - now sending rollback to valet");
                     try {
@@ -1231,17 +1202,10 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
                 }
                 throw new VnfException(me);
             } catch (NullPointerException npe) {
-                String error = "Create VFModule " + vfModuleType + " in " + cloudOwner + "/" + cloudSiteId + "/"
-                        + tenantId + ": " + npe;
-                logger.error("{} {} {} {} {} {} {} {}", MessageEnum.RA_CREATE_VNF_ERR.toString(), vfModuleType,
-                        cloudOwner, cloudSiteId, tenantId, OPENSTACK, ErrorCode.DataError.getValue(),
-                        "NullPointerException - createStack", npe);
-                logger.debug(error);
-                logger.debug("NULL POINTER EXCEPTION at heat.createStack");
-                // npe.addContext ("CreateVNF");
+                logger.error("Error creating Stack", npe);
                 throw new VnfException("NullPointerException during heat.createStack");
             } catch (Exception e) {
-                logger.debug("unhandled exception at heat.createStack", e);
+                logger.error("Error creating Stack", e);
                 throw new VnfException("Exception during heat.createStack! " + e.getMessage());
             }
             // Reach this point if createStack is successful.
@@ -1899,8 +1863,6 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
             } else {
                 logger.debug("found missing parameters - but checkRequiredParameters is false - will not block");
             }
-        } else {
-            logger.debug("No missing parameters found - ok to proceed");
         }
 
         // Just submit the envt entry as received from the database
index 4dcb7c8..add1918 100644 (file)
 
 package org.onap.so.adapters.network;
 
-import org.apache.http.HttpStatus;
-import org.junit.Test;
-import org.onap.so.adapters.vnf.BaseRestTestUtils;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.util.UriComponentsBuilder;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
 import static org.junit.Assert.assertEquals;
 import static org.onap.so.bpmn.mock.StubOpenStack.mockOpenStackDeleteNeutronNetwork;
 import static org.onap.so.bpmn.mock.StubOpenStack.mockOpenStackDeleteStack_200;
@@ -52,6 +40,18 @@ import static org.onap.so.bpmn.mock.StubOpenStack.mockOpenStackPutStack;
 import static org.onap.so.bpmn.mock.StubOpenStack.mockOpenStackResponseAccess;
 import static org.onap.so.bpmn.mock.StubOpenStack.mockOpenstackGet;
 import static org.onap.so.bpmn.mock.StubOpenStack.mockOpenstackPost;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.http.HttpStatus;
+import org.junit.Test;
+import org.onap.so.adapters.vnf.BaseRestTestUtils;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.util.UriComponentsBuilder;
 
 public class MSONetworkAdapterImplTest extends BaseRestTestUtils {
 
@@ -142,12 +142,12 @@ public class MSONetworkAdapterImplTest extends BaseRestTestUtils {
 
         mockOpenStackResponseAccess(wireMockServer, wireMockPort);
 
-        mockOpenStackGetStack_404(wireMockServer, "dvspg-VCE_VPE-mtjnj40avbc");
+        mockOpenStackGetStack_404(wireMockServer, "DEV-VF-1802-it3-pwt3-v6-vSAMP10a-addon2-Replace-1001/stackId");
 
         mockOpenStackPostStack_200(wireMockServer, "OpenstackResponse_Stack.json");
 
         mockOpenStackGetStackCreated_200(wireMockServer, "OpenstackResponse_Stack_Created.json",
-                "dvspg-VCE_VPE-mtjnj40avbc/stackId");
+                "DEV-VF-1802-it3-pwt3-v6-vSAMP10a-addon2-Replace-1001/stackId");
 
         String uri = "/services/NetworkAdapter";
         headers.set("X-ECOMP-RequestID", "123456789456127");
@@ -163,7 +163,7 @@ public class MSONetworkAdapterImplTest extends BaseRestTestUtils {
         mockOpenStackPostStack_200(wireMockServer, "OpenstackResponse_Stack.json");
 
         mockOpenStackGetStackCreated_200(wireMockServer, "OpenstackResponse_Stack_Created.json",
-                "dvspg-VCE_VPE-mtjnj40avbc");
+                "DEV-VF-1802-it3-pwt3-v6-vSAMP10a-addon2-Replace-1001/stackId");
 
         String uri = "/services/NetworkAdapter";
         headers.set("X-ECOMP-RequestID", "123456789456127");
index b9fc419..5ee33ab 100644 (file)
@@ -4,7 +4,7 @@
           <cloudSiteId>mtn13</cloudSiteId>
           <tenantId>bef254252c5d44e6bcec65c180180ab5</tenantId>
           <networkType>CONTRAIL30_GNDIRECT</networkType>
-          <networkName>dvspg-VCE_VPE-mtjnj40avbc</networkName>
+          <networkName>DEV-VF-1802-it3-pwt3-v6-vSAMP10a-addon2-Replace-1001</networkName>
           <physicalNetworkName>dvs-mtjnj-01</physicalNetworkName>
           <vlans>3014</vlans>
           <failIfExists>false</failIfExists>
index af63ca7..be50d09 100644 (file)
@@ -1,17 +1,15 @@
 {
-       "stack": {
-               "description": null,
-               "links": null,
-               "stackStatusReason": null,
-               "stackName": null,
-               "updatedTime": null,
-               "creationTime": null,
-               "stackStatus": "NOT_FOUND",
-               "id": "stackId",
-               "files": null,
-               "outputs": null,
-               "parameters": {
-                       
-               }
-       }
-}
\ No newline at end of file
+  "stack": {
+    "creationTime": null, 
+    "description": null, 
+    "files": null, 
+    "id": "stackId", 
+    "links": null, 
+    "outputs": null, 
+    "parameters": {}, 
+    "stack_name": "DEV-VF-1802-it3-pwt3-v6-vSAMP10a-addon2-Replace-1001", 
+    "stack_status": "CREATE_IN_PROGRESS", 
+    "stack_status_reason": null, 
+    "updatedTime": null
+  }
+}
index 29893cc..e49d407 100644 (file)
@@ -1,17 +1,15 @@
 {
-       "stack": {
-               "description": null,
-               "links": null,
-               "stack_status_reason": null,
-               "stack_name": "DEV-VF-1802-it3-pwt3-v6-vSAMP10a-addon2-Replace-1001",
-               "updated_time": null,
-               "creation_time": null,
-               "stack_status": "CREATE_COMPLETE",
-               "id": "stackId",
-               "files": null,
-               "outputs": null,
-               "parameters": {
-                       
-               }
-       }
-}
\ No newline at end of file
+  "stack": {
+    "creationTime": null, 
+    "description": null, 
+    "files": null, 
+    "id": "stackId", 
+    "links": null, 
+    "outputs": null, 
+    "parameters": {}, 
+    "stack_name": "DEV-VF-1802-it3-pwt3-v6-vSAMP10a-addon2-Replace-1001", 
+    "stack_status": "CREATE_COMPLETE", 
+    "stack_status_reason": "Create Completed", 
+    "updatedTime": null
+  }
+}
index 8612258..bad85f3 100644 (file)
@@ -3,7 +3,7 @@
                "description": null,
                "links": null,
                "stackStatusReason": null,
-               "stackName": null,
+               "stackName": "stackName",
                "updatedTime": null,
                "creationTime": null,
                "stack_status": "DELETE_COMPLETE",
index f4a3c52..70c78a6 100644 (file)
@@ -7,6 +7,7 @@
                        "rel" : "self"
                        }
                ],
-               "stack_name": "vnfBaseStack"
+               "stack_name": "vnfBaseStack",
+               "stack_status": "CREATE_COMPLETE"
        }
 }
\ No newline at end of file
index 5d6eee7..8bfa6d8 100644 (file)
     </appender>
 
 
-  <logger name="com.att.eelf.audit" level="INFO" additivity="false">
-    <appender-ref ref="STDOUT" />
-  </logger>
-  
-  <logger name="com.att.eelf.metrics" level="INFO" additivity="false">
-        <appender-ref ref="STDOUT" />
-  </logger>
 
-  <logger name="com.att.eelf.error" level="WARN" additivity="false">
+  <logger name="com.woorea.openstack" level="${so.log.level:-DEBUG}" additivity="false">
     <appender-ref ref="STDOUT" />
   </logger> 
   
  <logger name="org.onap" level="${so.log.level:-DEBUG}" additivity="false">
     <appender-ref ref="STDOUT" />
   </logger>
-  
-   <logger name="org.onap" level="${so.log.level:-DEBUG}" additivity="false">
-    <appender-ref ref="STDOUT" />
-  </logger> 
+
 
   <root level="WARN">
     <appender-ref ref="STDOUT" />
index 380381f..c09c5f0 100644 (file)
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.onap.so.vnfm</groupId>
-        <artifactId>vnfm-simulator</artifactId>
-        <version>1.4.0-SNAPSHOT</version>
-    </parent>
-    <artifactId>vnfm-service</artifactId>
-    <name>${project.artifactId}</name>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.onap.so.vnfm</groupId>
+    <artifactId>vnfm-simulator</artifactId>
+    <version>1.4.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>vnfm-service</artifactId>
+  <name>${project.artifactId}</name>
 
-    <properties>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <java.version>1.8</java.version>
-        <okhttp-version>2.7.5</okhttp-version>
-        <gson-version>2.8.1</gson-version>
-    </properties>
-    <dependencies>
-        <dependency>
-            <groupId>org.onap.so.adapters</groupId>
-            <artifactId>mso-vnfm-adapter-ext-clients</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-web</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-data-jpa</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-actuator</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-devtools</artifactId>
-            <scope>runtime</scope>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>io.swagger</groupId>
-            <artifactId>swagger-jaxrs</artifactId>
-            <version>1.5.0</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.directory.studio</groupId>
-            <artifactId>org.apache.commons.io</artifactId>
-            <version>2.4</version>
-        </dependency>
-        <dependency>
-            <groupId>com.googlecode.json-simple</groupId>
-            <artifactId>json-simple</artifactId>
-            <version>1.1.1</version>
-        </dependency>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <java.version>1.8</java.version>
+    <okhttp-version>2.7.5</okhttp-version>
+    <gson-version>2.8.1</gson-version>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.onap.so.adapters</groupId>
+      <artifactId>mso-vnfm-adapter-ext-clients</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-web</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-data-jpa</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-actuator</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-test</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-devtools</artifactId>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>io.swagger</groupId>
+      <artifactId>swagger-jaxrs</artifactId>
+      <version>1.5.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.directory.studio</groupId>
+      <artifactId>org.apache.commons.io</artifactId>
+      <version>2.4</version>
+    </dependency>
+    <dependency>
+      <groupId>com.googlecode.json-simple</groupId>
+      <artifactId>json-simple</artifactId>
+      <version>1.1.1</version>
+    </dependency>
 
-        <dependency>
-            <groupId>io.springfox</groupId>
-            <artifactId>springfox-swagger-ui</artifactId>
-            <version>2.6.1</version>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>io.springfox</groupId>
-            <artifactId>springfox-swagger2</artifactId>
-            <version>2.6.1</version>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-databind</artifactId>
-            <version>2.9.8</version>
-        </dependency>
-        <dependency>
-            <groupId>com.h2database</groupId>
-            <artifactId>h2</artifactId>
-        </dependency>
-        <!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
-        <dependency>
-            <groupId>commons-beanutils</groupId>
-            <artifactId>commons-beanutils</artifactId>
-            <version>1.9.3</version>
-        </dependency>
-        <dependency>
-            <groupId>org.modelmapper</groupId>
-            <artifactId>modelmapper</artifactId>
-            <version>2.3.0</version>
-        </dependency>
-        <dependency>
-            <groupId>com.squareup.okio</groupId>
-            <artifactId>okio</artifactId>
-            <version>1.13.0</version>
-        </dependency>
-        <dependency>
-            <groupId>com.squareup.okhttp</groupId>
-            <artifactId>okhttp</artifactId>
-            <version>${okhttp-version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.squareup.okhttp</groupId>
-            <artifactId>logging-interceptor</artifactId>
-            <version>${okhttp-version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.google.code.gson</groupId>
-            <artifactId>gson</artifactId>
-            <version>${gson-version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.onap.so</groupId>
-            <artifactId>common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-    </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.springframework.boot</groupId>
-                <artifactId>spring-boot-maven-plugin</artifactId>
-                <version>${springboot.version}</version>
-                <configuration>
-                    <mainClass>org.onap.svnfm.simulator.config.SvnfmApplication</mainClass>
-                </configuration>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>repackage</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
-                <groupId>org.springframework.boot</groupId>
-                <artifactId>spring-boot-maven-plugin</artifactId>
-            </plugin>
-        </plugins>
-    </build>
+    <dependency>
+      <groupId>io.springfox</groupId>
+      <artifactId>springfox-swagger-ui</artifactId>
+      <version>2.6.1</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>io.springfox</groupId>
+      <artifactId>springfox-swagger2</artifactId>
+      <version>2.6.1</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
+      <version>2.9.8</version>
+    </dependency>
+    <dependency>
+      <groupId>com.h2database</groupId>
+      <artifactId>h2</artifactId>
+    </dependency>
+    <!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
+    <dependency>
+      <groupId>commons-beanutils</groupId>
+      <artifactId>commons-beanutils</artifactId>
+      <version>1.9.3</version>
+    </dependency>
+    <dependency>
+      <groupId>org.modelmapper</groupId>
+      <artifactId>modelmapper</artifactId>
+      <version>2.3.0</version>
+    </dependency>
+    <dependency>
+      <groupId>com.squareup.okio</groupId>
+      <artifactId>okio</artifactId>
+      <version>1.13.0</version>
+    </dependency>
+    <dependency>
+      <groupId>com.squareup.okhttp</groupId>
+      <artifactId>okhttp</artifactId>
+      <version>${okhttp-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.squareup.okhttp</groupId>
+      <artifactId>logging-interceptor</artifactId>
+      <version>${okhttp-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <version>${gson-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.onap.so</groupId>
+      <artifactId>common</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-maven-plugin</artifactId>
+        <version>${springboot.version}</version>
+        <configuration>
+          <mainClass>org.onap.svnfm.simulator.config.SvnfmApplication</mainClass>
+        </configuration>
+        <executions>
+          <execution>
+            <goals>
+              <goal>repackage</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-maven-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
 </project>