Merge "add maven build properties to spring actuator"
authorSteve Smokowski <ss835w@att.com>
Mon, 4 Feb 2019 13:40:39 +0000 (13:40 +0000)
committerGerrit Code Review <gerrit@onap.org>
Mon, 4 Feb 2019 13:40:39 +0000 (13:40 +0000)
47 files changed:
adapters/mso-adapter-utils/src/main/java/org/onap/so/audit/beans/AuditInventory.java [new file with mode: 0644]
adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java
adapters/mso-openstack-adapters/pom.xml
adapters/mso-openstack-adapters/src/main/java/db/migration/R__CloudConfigMigration.java
adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AbstractAudit.java [new file with mode: 0644]
adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackService.java [new file with mode: 0644]
adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackServiceData.java [new file with mode: 0644]
adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditVServer.java [new file with mode: 0644]
adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/HeatStackAudit.java [new file with mode: 0644]
adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/AaiClientPropertiesImpl.java [new file with mode: 0644]
adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/MsoOpenstackAdaptersApplication.java
adapters/mso-openstack-adapters/src/main/resources/META-INF/services/org.onap.so.client.RestProperties [new file with mode: 0644]
adapters/mso-openstack-adapters/src/main/resources/application.yaml
adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/AuditStackServiceDataTest.java [new file with mode: 0644]
adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/AuditVServerTest.java [new file with mode: 0644]
adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/HeatStackAuditTest.java [new file with mode: 0644]
adapters/mso-openstack-adapters/src/test/resources/AVPNResourceGroupResponse.json [new file with mode: 0644]
adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface0.json [new file with mode: 0644]
adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface0Resources.json [new file with mode: 0644]
adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface1.json [new file with mode: 0644]
adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface1Resources.json [new file with mode: 0644]
adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface2.json [new file with mode: 0644]
adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface2Resources.json [new file with mode: 0644]
adapters/mso-openstack-adapters/src/test/resources/GetResources.json [new file with mode: 0644]
adapters/mso-openstack-adapters/src/test/resources/MISResourceGroupResponse.json [new file with mode: 0644]
adapters/mso-openstack-adapters/src/test/resources/MISSubInterface0.json [new file with mode: 0644]
adapters/mso-openstack-adapters/src/test/resources/MISSubInterface1Resources.json [new file with mode: 0644]
adapters/mso-openstack-adapters/src/test/resources/logback-test.xml
asdc-controller/src/main/java/org/onap/so/asdc/installer/heat/ToscaResourceInstaller.java
bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/ExecuteBuildingBlockRainyDay.java
bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/exception/ExceptionBuilder.java
bpmn/MSOCommonBPMN/src/test/java/org/onap/so/bpmn/servicedecomposition/tasks/ExecuteBuildlingBlockRainyDayTest.java
bpmn/mso-infrastructure-bpmn/src/main/resources/application.yaml
bpmn/so-bpmn-building-blocks/pom.xml
bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ActivateVfModuleBB.bpmn
bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CreateVfModuleBB.bpmn
bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ExecuteBuildingBlock.bpmn
bpmn/so-bpmn-building-blocks/src/test/java/org/onap/so/bpmn/BaseBPMNTest.java
bpmn/so-bpmn-building-blocks/src/test/java/org/onap/so/bpmn/infrastructure/bpmn/subprocess/ActivateVfModuleBBTest.java
bpmn/so-bpmn-building-blocks/src/test/resources/application-test.yaml
bpmn/so-bpmn-building-blocks/src/test/resources/logback-test.xml
bpmn/so-bpmn-tasks/pom.xml
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/audit/AuditTasks.java [new file with mode: 0644]
bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/audit/AuditTasksTest.java [new file with mode: 0644]
common/src/main/java/org/onap/so/client/aai/AAIObjectPlurals.java
common/src/main/java/org/onap/so/client/aai/AAIObjectType.java
mso-api-handlers/mso-api-handler-infra/src/main/resources/application.yaml

diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/audit/beans/AuditInventory.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/audit/beans/AuditInventory.java
new file mode 100644 (file)
index 0000000..025d40d
--- /dev/null
@@ -0,0 +1,74 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017-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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.audit.beans;
+
+import java.io.Serializable;
+
+public class AuditInventory implements Serializable{
+       
+       /**
+        * 
+        */
+       private static final long serialVersionUID = 4937350343452380760L;
+
+       private String cloudRegion;
+       
+       private String cloudOwner;
+       
+       private String tenantId;
+       
+       private String heatStackName;
+
+       public String getCloudRegion() {
+               return cloudRegion;
+       }
+
+       public void setCloudRegion(String cloudRegion) {
+               this.cloudRegion = cloudRegion;
+       }
+
+       public String getCloudOwner() {
+               return cloudOwner;
+       }
+
+       public void setCloudOwner(String cloudOwner) {
+               this.cloudOwner = cloudOwner;
+       }
+
+       public String getTenantId() {
+               return tenantId;
+       }
+
+       public void setTenantId(String tenantId) {
+               this.tenantId = tenantId;
+       }
+
+       public String getHeatStackName() {
+               return heatStackName;
+       }
+
+       public void setHeatStackName(String heatStackName) {
+               this.heatStackName = heatStackName;
+       }
+       
+       
+
+}
index f132f10..14aee2f 100644 (file)
@@ -29,6 +29,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Optional;
 import java.util.Set;
 
 import org.onap.so.adapters.vdu.CloudInfo;
@@ -79,6 +80,7 @@ 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.Resources;
 import com.woorea.openstack.heat.model.Stack;
 import com.woorea.openstack.heat.model.Stack.Output;
 import com.woorea.openstack.heat.model.Stacks;
@@ -311,37 +313,23 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{
 
         Stack heatStack = null;
         try {
-            // Execute the actual Openstack command to create the Heat stack
             OpenStackRequest <Stack> request = heatClient.getStacks ().create (stack);
-            // Begin X-Auth-User
-            // Obtain an MSO token for the tenant
             CloudIdentity cloudIdentity = cloudSite.getIdentityService();
-            // cloudIdentity.getMsoId(), cloudIdentity.getMsoPass()
-            //req
             request.header ("X-Auth-User", cloudIdentity.getMsoId ());
             request.header ("X-Auth-Key", CryptoUtils.decryptCloudConfigPassword(cloudIdentity.getMsoPass ()));
-            LOGGER.debug ("headers added, about to executeAndRecordOpenstackRequest");
-            //LOGGER.debug(this.requestToStringBuilder(stack).toString());
-            // END - try to fix X-Auth-User
             heatStack = executeAndRecordOpenstackRequest (request);
         } catch (OpenStackResponseException e) {
-            // Since this came on the 'Create Stack' command, nothing was changed
-            // in the cloud. Return the error as an exception.
-            if (e.getStatus () == 409) {
-                // Stack already exists. Return a specific error for this case
+            if (e.getStatus () == 409) {                
                 MsoStackAlreadyExists me = new MsoStackAlreadyExists (stackName, tenantId, cloudSiteId);
                 me.addContext (CREATE_STACK);
                 throw me;
-            } else {
-                // Convert the OpenStackResponseException to an MsoOpenstackException
+        } else {
                 LOGGER.debug("ERROR STATUS = " + e.getStatus() + ",\n" + e.getMessage() + "\n" + e.getLocalizedMessage());
                 throw heatExceptionToMsoException (e, CREATE_STACK);
             }
-        } catch (OpenStackConnectException e) {
-            // Error connecting to Openstack instance. Convert to an MsoException
+        } catch (OpenStackConnectException e) {          
             throw heatExceptionToMsoException (e, CREATE_STACK);
-        } catch (RuntimeException e) {
-            // Catch-all
+        } catch (RuntimeException e) {           
             throw runtimeExceptionToMsoException (e, CREATE_STACK);
         }
 
@@ -349,211 +337,197 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{
         // Otherwise, simple query by name returns a 302 redirect.
         // NOTE: This is specific to the v1 Orchestration API.
         String canonicalName = stackName + "/" + heatStack.getId ();
-
-        // If client has requested a final response, poll for stack completion
+       
         if (pollForCompletion) {
-            // Set a time limit on overall polling.
-            // Use the resource (template) timeout for Openstack (expressed in minutes)
-            // and add one poll interval to give Openstack a chance to fail on its own.s
-
-            int createPollInterval = Integer.parseInt(this.environment.getProperty(createPollIntervalProp, createPollIntervalDefault));
-            int pollTimeout = (timeoutMinutes * 60) + createPollInterval;
-            // New 1610 - poll on delete if we rollback - use same values for now
-            int deletePollInterval = createPollInterval;
-            int deletePollTimeout = pollTimeout;
-            boolean createTimedOut = false;
-            StringBuilder stackErrorStatusReason = new StringBuilder("");
-            LOGGER.debug("createPollInterval=" + createPollInterval + ", pollTimeout=" + pollTimeout);
-
-            while (true) {
-                try {
-                    heatStack = queryHeatStack (heatClient, canonicalName);
-                    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);
-                    }
-
-                    if ("CREATE_IN_PROGRESS".equals (heatStack.getStackStatus ())) {
-                        // Stack creation is still running.
-                        // Sleep and try again unless timeout has been reached
-                        if (pollTimeout <= 0) {
-                            // Note that this should not occur, since there is a timeout specified
-                            // in the Openstack call.
-                            LOGGER.error (MessageEnum.RA_CREATE_STACK_TIMEOUT, cloudSiteId, tenantId, stackName, heatStack.getStackStatus (), "", "", MsoLogger.ErrorCode.AvailabilityError, "Create stack timeout");
-                            createTimedOut = true;
-                            break;
-                        }
-
-                        sleep(createPollInterval * 1000L);
-
-                        pollTimeout -= createPollInterval;
-                               LOGGER.debug("pollTimeout remaining: " + pollTimeout);
-                    } else {
-                       //save off the status & reason msg before we attempt delete
-                       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(MessageEnum.RA_CREATE_STACK_ERR, "Create Stack errored, stack deletion suppressed", "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in Create Stack, stack deletion suppressed");
-                       }
-                       else
-                       {
-                               try {
-                                       LOGGER.debug("Create Stack error - unable to query for stack status - attempting to delete stack: " + canonicalName + " - This will likely fail and/or we won't be able to query to see if delete worked");
-                                       OpenStackRequest <Void> request = heatClient.getStacks ().deleteByName (canonicalName);
-                                       executeAndRecordOpenstackRequest (request);
-                                       // this may be a waste of time - if we just got an exception trying to query the stack - we'll just
-                                       // get another one, n'est-ce pas?
-                                       boolean deleted = false;
-                                       while (!deleted) {
-                                               try {
-                                                       heatStack = queryHeatStack(heatClient, canonicalName);
-                                                       if (heatStack != null) {
-                                                       LOGGER.debug(heatStack.getStackStatus());
-                                                       if ("DELETE_IN_PROGRESS".equals(heatStack.getStackStatus())) {
-                                                               if (deletePollTimeout <= 0) {
-                                                                       LOGGER.error (MessageEnum.RA_CREATE_STACK_TIMEOUT, cloudSiteId, tenantId, stackName,
-                                                                                       heatStack.getStackStatus (), "", "", MsoLogger.ErrorCode.AvailabilityError,
-                                                                                       "Rollback: DELETE stack timeout");
-                                                                       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 " + canonicalName + " has been deleted");
-                                                       deleted = true;
-                                                       continue;
-                                                       }
-
-                                               } catch (Exception e3) {
-                                                       // Just log this one. We will report the original exception.
-                                                       LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Create Stack: Nested exception rolling back stack: " + e3, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack: Nested exception rolling back stack on error on query");
-
-                                               }
-                                       }
-                               } catch (Exception e2) {
-                                       // Just log this one. We will report the original exception.
-                                       LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Create Stack: Nested exception rolling back stack: " + e2, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack: Nested exception rolling back stack");
-                               }
-                       }
-
-                    // Propagate the original exception from Stack Query.
-                    me.addContext (CREATE_STACK);
-                    throw me;
-                }
-            }
-
-            if (!"CREATE_COMPLETE".equals (heatStack.getStackStatus ())) {
-                LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Create Stack error:  Polling complete with non-success status: "
-                              + heatStack.getStackStatus () + ", " + heatStack.getStackStatusReason (), "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack error");
-
-                // Rollback the stack creation, since it is in an indeterminate state.
-                if (!backout)
-                {
-                       LOGGER.warn(MessageEnum.RA_CREATE_STACK_ERR, "Create Stack errored, stack deletion suppressed", "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack error, stack deletion suppressed");
-                }
-                else
-                {
-                       try {
-                               LOGGER.debug("Create Stack errored - attempting to DELETE stack: " + canonicalName);
-                               LOGGER.debug("deletePollInterval=" + deletePollInterval + ", deletePollTimeout=" + 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 (MessageEnum.RA_CREATE_STACK_TIMEOUT, cloudSiteId, tenantId, stackName,
-                                                                                       heatStack.getStackStatus (), "", "", MsoLogger.ErrorCode.AvailabilityError,
-                                                                                       "Rollback: DELETE stack timeout");
-                                                                       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(MessageEnum.RA_CREATE_STACK_ERR, "Create Stack errored, stack deletion FAILED", "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack error, stack deletion FAILED");
-                                                               LOGGER.debug("Stack deletion FAILED on a rollback of a create - " + canonicalName + ", status=" + heatStack.getStackStatus() + ", reason=" + 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 " + canonicalName + " has been deleted");
-                                                       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 " + canonicalName + " on a create->rollback: " + me2.getContextMessage(), me2);
-                                               LOGGER.warn(MessageEnum.RA_CREATE_STACK_ERR, "Create Stack errored, then stack deletion FAILED - exception thrown", "", "", MsoLogger.ErrorCode.BusinessProcesssError, 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");
-                               }
-//                             MsoOpenstackException me = new MsoOpenstackException(0, "", stackErrorStatusReason.toString());
- //                            me.addContext(CREATE_STACK);
-
-   //                          throw me;
-                       } catch (Exception e2) {
-                               // shouldn't happen - but handle
-                               LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Create Stack: Nested exception rolling back stack: " + e2, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in Create Stack: rolling back stack");
-                       }
-                }
-                MsoOpenstackException me = new MsoOpenstackException(0, "", stackErrorStatusReason.toString());
-                me.addContext(CREATE_STACK);
-
-                throw me;
-            }
-
+            heatStack = pollStackForCompletion(cloudSiteId, tenantId, stackName, timeoutMinutes, backout, heatClient,
+                                       heatStack, canonicalName);
         } else {
             // Get initial status, since it will have been null after the create.
             heatStack = queryHeatStack (heatClient, canonicalName);
             LOGGER.debug (heatStack.getStackStatus ());
         }
-
         return new StackInfoMapper(heatStack).map();
     }
 
+       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, createPollIntervalDefault));
+               int pollTimeout = (timeoutMinutes * 60) + createPollInterval;
+               int deletePollInterval = createPollInterval;
+               int deletePollTimeout = pollTimeout;
+               boolean createTimedOut = false;
+               StringBuilder stackErrorStatusReason = new StringBuilder("");
+               LOGGER.debug("createPollInterval=" + createPollInterval + ", pollTimeout=" + pollTimeout);
+
+               while (true) {
+                   try {
+                       heatStack = queryHeatStack (heatClient, canonicalName);
+                       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);
+                       }
+
+                       if ("CREATE_IN_PROGRESS".equals (heatStack.getStackStatus ())) {                       
+                           if (pollTimeout <= 0) {
+                               LOGGER.error (MessageEnum.RA_CREATE_STACK_TIMEOUT, cloudSiteId, tenantId, stackName, heatStack.getStackStatus (), "", "", MsoLogger.ErrorCode.AvailabilityError, "Create stack timeout");
+                               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(MessageEnum.RA_CREATE_STACK_ERR, "Create Stack errored, stack deletion suppressed", "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in Create Stack, stack deletion suppressed");
+                       }
+                       else
+                       {
+                               try {
+                                       LOGGER.debug("Create Stack error - unable to query for stack status - attempting to delete stack: " + canonicalName + " - This will likely fail and/or we won't be able to query to see if delete worked");
+                                       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());
+                                                               if ("DELETE_IN_PROGRESS".equals(heatStack.getStackStatus())) {
+                                                                       if (deletePollTimeout <= 0) {
+                                                                               LOGGER.error (MessageEnum.RA_CREATE_STACK_TIMEOUT, cloudSiteId, tenantId, stackName,
+                                                                                               heatStack.getStackStatus (), "", "", MsoLogger.ErrorCode.AvailabilityError,
+                                                                                               "Rollback: DELETE stack timeout");
+                                                                               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 " + canonicalName + " has been deleted");
+                                                               deleted = true;
+                                                               continue;
+                                                       }
+
+                                               } catch (Exception e3) {
+                                                       // Just log this one. We will report the original exception.
+                                                       LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Create Stack: Nested exception rolling back stack: " + e3, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack: Nested exception rolling back stack on error on query");
+
+                                               }
+                                       }
+                               } catch (Exception e2) {
+                                       // Just log this one. We will report the original exception.
+                                       LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Create Stack: Nested exception rolling back stack: " + e2, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack: Nested exception rolling back stack");
+                               }
+                       }
+
+                       // Propagate the original exception from Stack Query.
+                       me.addContext (CREATE_STACK);
+                       throw me;
+                   }
+               }
+
+               if (!"CREATE_COMPLETE".equals (heatStack.getStackStatus ())) {
+                   LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Create Stack error:  Polling complete with non-success status: "
+                                 + heatStack.getStackStatus () + ", " + heatStack.getStackStatusReason (), "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack error");
+
+                   // Rollback the stack creation, since it is in an indeterminate state.
+                   if (!backout)
+                   {
+                       LOGGER.warn(MessageEnum.RA_CREATE_STACK_ERR, "Create Stack errored, stack deletion suppressed", "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack error, stack deletion suppressed");
+                   }
+                   else
+                   {
+                       try {
+                               LOGGER.debug("Create Stack errored - attempting to DELETE stack: " + canonicalName);
+                               LOGGER.debug("deletePollInterval=" + deletePollInterval + ", deletePollTimeout=" + 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 (MessageEnum.RA_CREATE_STACK_TIMEOUT, cloudSiteId, tenantId, stackName,
+                                                                                       heatStack.getStackStatus (), "", "", MsoLogger.ErrorCode.AvailabilityError,
+                                                                                       "Rollback: DELETE stack timeout");
+                                                                       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(MessageEnum.RA_CREATE_STACK_ERR, "Create Stack errored, stack deletion FAILED", "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack error, stack deletion FAILED");
+                                                               LOGGER.debug("Stack deletion FAILED on a rollback of a create - " + canonicalName + ", status=" + heatStack.getStackStatus() + ", reason=" + 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 " + canonicalName + " has been deleted");
+                                                       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 " + canonicalName + " on a create->rollback: " + me2.getContextMessage(), me2);
+                                               LOGGER.warn(MessageEnum.RA_CREATE_STACK_ERR, "Create Stack errored, then stack deletion FAILED - exception thrown", "", "", MsoLogger.ErrorCode.BusinessProcesssError, 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 (MessageEnum.RA_CREATE_STACK_ERR, "Create Stack: Nested exception rolling back stack: " + e2, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in Create Stack: rolling back stack");
+                       }
+                   }
+                   MsoOpenstackException me = new MsoOpenstackException(0, "", stackErrorStatusReason.toString());
+                   me.addContext(CREATE_STACK);
+                   throw me;
+               }
+               return heatStack;
+       }
+
     /**
      * Query for a single stack (by Name) in a tenant. This call will always return a
      * StackInfo object. If the stack does not exist, an "empty" StackInfo will be
@@ -1231,7 +1205,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{
                sb.append("[END]");
                return sb;
        }
-
 
        public void copyBaseOutputsToInputs(Map<String, Object> inputs,
                        Map<String, Object> otherStackOutputs, List<String> paramNames, Map<String, String> aliases) {
@@ -1727,6 +1701,22 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{
 
        return vduStatus;
     }
+    
+       public Resources queryStackResources(String cloudSiteId, String tenantId, String stackName) throws MsoException {
+               CloudSite cloudSite = cloudConfig.getCloudSite(cloudSiteId)
+                               .orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
+               Heat heatClient = getHeatClient(cloudSite, tenantId);
+               OpenStackRequest<Resources> request = heatClient.getResources().listResources(stackName);
+               return executeAndRecordOpenstackRequest(request);
+       }
+
+       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);
+               OpenStackRequest<R> request = heatClient.get(url, returnType);
+               return executeAndRecordOpenstackRequest(request);
+       }
 
     protected void sleep(long time) {
        try {
index 743c50d..8d4f30b 100644 (file)
                        <artifactId>cxf-logging</artifactId>
                        <version>${project.version}</version>
                </dependency>
+               <dependency>
+                       <groupId>org.onap.so.libs.openstack-java-sdk</groupId>
+            <artifactId>nova-model</artifactId>
+                       <version>${openstack.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.camunda.bpm</groupId>
+                       <artifactId>camunda-external-task-client</artifactId>
+                       <version>1.2.0-SNAPSHOT</version>
+               </dependency>   
        </dependencies>
 </project>
index 257ad3c..5acd835 100644 (file)
@@ -65,7 +65,22 @@ public class R__CloudConfigMigration implements JdbcMigration , MigrationInfoPro
         LOGGER.debug("Starting migration for CloudConfig");
         
         CloudConfig cloudConfig = null;
-
+        
+        String tableQuery = "SELECT * FROM identity_services";
+        int totalRetries = 20;
+        boolean tableExists = false;
+        int count = 1;
+        while(!tableExists && count != totalRetries) {
+               try(Statement stmt = connection.createStatement();) {
+               stmt.executeQuery(tableQuery);
+               tableExists = true;
+            } catch (SQLException e) {
+               count++;
+               // Wait 5 mintues
+               Thread.sleep(300000);
+            }
+        }
+        
         // Try the override file
         String configLocation = System.getProperty("spring.config.additional-location");
         if (configLocation != null) {
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AbstractAudit.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AbstractAudit.java
new file mode 100644 (file)
index 0000000..292cebf
--- /dev/null
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.adapters.audit;
+
+import org.onap.so.client.aai.AAIResourcesClient;
+
+public class AbstractAudit {
+       
+       private AAIResourcesClient aaiClient;
+
+       protected AAIResourcesClient getAaiClient(){
+               if(aaiClient == null)
+                       return new AAIResourcesClient();
+               else
+                       return aaiClient;
+       }
+       
+       protected void setAaiClient(AAIResourcesClient aaiResource){
+               aaiClient = aaiResource;
+       }
+}
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackService.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackService.java
new file mode 100644 (file)
index 0000000..38b0068
--- /dev/null
@@ -0,0 +1,68 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.adapters.audit;
+
+import java.security.GeneralSecurityException;
+
+import javax.annotation.PostConstruct;
+
+import org.camunda.bpm.client.ExternalTaskClient;
+import org.camunda.bpm.client.backoff.ExponentialBackoffStrategy;
+import org.camunda.bpm.client.interceptor.ClientRequestInterceptor;
+import org.camunda.bpm.client.interceptor.auth.BasicAuthProvider;
+import org.onap.so.utils.CryptoUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+
+@Component
+@Profile("!test")
+public class AuditStackService {
+
+       private static final Logger logger = LoggerFactory.getLogger(AuditStackService.class);
+
+       @Autowired
+       public Environment env;
+
+       @Autowired
+       private AuditStackServiceData auditStack;
+
+       @PostConstruct
+       public void auditAAIInventory() {
+               String auth = "";
+               try {
+                       auth = CryptoUtils.decrypt(env.getRequiredProperty("mso.auth"), env.getRequiredProperty("mso.msoKey"));
+               } catch (IllegalStateException | GeneralSecurityException e) {
+                       logger.error("Error Decrypting Password", e);
+               }
+               ClientRequestInterceptor interceptor = new BasicAuthProvider(env.getRequiredProperty("mso.config.cadi.aafId"),
+                               auth);
+               ExternalTaskClient client = ExternalTaskClient.create()
+                               .baseUrl(env.getRequiredProperty("mso.workflow.endpoint")).maxTasks(5).addInterceptor(interceptor)
+                               .asyncResponseTimeout(120000).backoffStrategy(new ExponentialBackoffStrategy(0, 0, 0)).build();
+               client.subscribe("InventoryAudit").lockDuration(5000)
+                               .handler(auditStack::executeExternalTask).open();
+       }
+
+}
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackServiceData.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackServiceData.java
new file mode 100644 (file)
index 0000000..b036939
--- /dev/null
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017-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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.adapters.audit;
+
+import java.util.Collections;
+
+import org.camunda.bpm.client.task.ExternalTask;
+import org.camunda.bpm.client.task.ExternalTaskService;
+import org.onap.so.audit.beans.AuditInventory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AuditStackServiceData {
+       
+       private static final String UNABLE_TO_FIND_ALL_V_SERVERS_AND_L_INTERACES_IN_A_AI = "Unable to find all VServers and L-Interaces in A&AI";
+       
+       private static final int[] RETRY_SEQUENCE = new int[] { 1, 1, 2, 3, 5, 8, 13, 20};
+
+       
+       private static final Logger logger = LoggerFactory.getLogger(AuditStackServiceData.class);
+       
+       @Autowired
+       public HeatStackAudit heatStackAudit; 
+       
+       @Autowired
+       public Environment env;
+
+       protected void executeExternalTask(ExternalTask externalTask, ExternalTaskService externalTaskService){
+               AuditInventory auditInventory = externalTask.getVariable("auditInventory");
+               boolean success = false;
+               try {
+                       logger.info("Executing External Task Audit Inventory, Retry Number: {} \n {}", auditInventory,externalTask.getRetries());
+                       success=heatStackAudit.auditHeatStack(auditInventory.getCloudRegion(), auditInventory.getCloudOwner(),
+                                       auditInventory.getTenantId(), auditInventory.getHeatStackName());
+               } catch (Exception e) {
+                       logger.error("Error during audit of stack", e);
+               }
+               
+               if (success) {
+                       externalTaskService.complete(externalTask);
+                       logger.debug("The External Task Id: {}  Successful", externalTask.getId());
+               } else {
+                       if(externalTask.getRetries() == null){
+                               logger.debug("The External Task Id: {}  Failed, Setting Retries to Default Start Value: {}", externalTask.getId(),RETRY_SEQUENCE.length);
+                               externalTaskService.handleFailure(externalTask, UNABLE_TO_FIND_ALL_V_SERVERS_AND_L_INTERACES_IN_A_AI, UNABLE_TO_FIND_ALL_V_SERVERS_AND_L_INTERACES_IN_A_AI, RETRY_SEQUENCE.length, 10000);                      
+                       }else if(externalTask.getRetries() != null &&
+                                       externalTask.getRetries()-1 == 0){
+                               logger.debug("The External Task Id: {}  Failed, All Retries Exhausted", externalTask.getId());
+                               externalTaskService.handleBpmnError(externalTask, "AuditAAIInventoryFailure", "Number of Retries Exceeded auditing inventory");
+                       }else{
+                               logger.debug("The External Task Id: {}  Failed, Decrementing Retries: {} , Retry Delay: ", externalTask.getId(),externalTask.getRetries()-1, calculateRetryDelay(externalTask.getRetries()));
+                               externalTaskService.handleFailure(externalTask, UNABLE_TO_FIND_ALL_V_SERVERS_AND_L_INTERACES_IN_A_AI, UNABLE_TO_FIND_ALL_V_SERVERS_AND_L_INTERACES_IN_A_AI, externalTask.getRetries()-1, calculateRetryDelay(externalTask.getRetries()));
+                       }
+                       logger.debug("The External Task Id: {} Failed", externalTask.getId());
+               }
+               
+               
+       }
+       protected long calculateRetryDelay(int currentRetries){
+               int retrySequence = RETRY_SEQUENCE.length - currentRetries;
+               long retryMultiplier = Long.parseLong(env.getProperty("mso.workflow.topics.retryMultiplier","6000"));
+               return RETRY_SEQUENCE[retrySequence] * retryMultiplier;
+       }
+}
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditVServer.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditVServer.java
new file mode 100644 (file)
index 0000000..6e6ecd5
--- /dev/null
@@ -0,0 +1,111 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.adapters.audit;
+
+import java.util.Optional;
+import java.util.Set;
+
+import org.onap.aai.domain.yang.LInterface;
+import org.onap.aai.domain.yang.LInterfaces;
+import org.onap.aai.domain.yang.Vserver;
+import org.onap.so.client.aai.AAIObjectPlurals;
+import org.onap.so.client.aai.AAIObjectType;
+import org.onap.so.client.aai.entities.AAIResultWrapper;
+import org.onap.so.client.aai.entities.uri.AAIResourceUri;
+import org.onap.so.client.aai.entities.uri.AAIUriFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AuditVServer extends AbstractAudit {
+       private static final Logger logger = LoggerFactory.getLogger(AuditVServer.class);
+
+       public boolean auditVservers(Set<Vserver> vServersToAudit, String tenantId, String cloudOwner, String cloudRegion) {
+               if (vServersToAudit == null || vServersToAudit.isEmpty()){
+                       return false;
+               }
+               return vServersToAudit.stream()
+                               .filter(vServer -> !doesVServerExistInAAI(vServer, tenantId, cloudOwner, cloudRegion)).findFirst()
+                               .map(v -> false).orElse(true);
+       }
+
+       private boolean doesVServerExistInAAI(Vserver vServer, String tenantId, String cloudOwner, String cloudRegion) {
+               AAIResourceUri vserverURI = AAIUriFactory.createResourceUri(AAIObjectType.VSERVER, cloudOwner, cloudRegion,
+                               tenantId, vServer.getVserverId());
+               boolean vServerExists = getAaiClient().exists(vserverURI);
+               boolean doesExist = getAaiClient().exists(vserverURI);
+               logger.info("v-server {} exists: {}", vServer.getVserverId(), doesExist);
+               boolean allNeutronNetworksExist = true;
+               if (vServerExists && vServer.getLInterfaces() != null) {
+                       allNeutronNetworksExist = vServer.getLInterfaces()
+                                       .getLInterface().stream().filter(lInterface -> !doesLinterfaceExistinAAI(lInterface,
+                                                       vServer.getVserverId(), tenantId, cloudOwner, cloudRegion))
+                                       .findFirst().map(v -> false).orElse(true);
+               }
+               return vServerExists && allNeutronNetworksExist;
+       }
+
+       private boolean doesLinterfaceExistinAAI(LInterface lInterface, String vServerId, String tenantId,
+                       String cloudOwner, String cloudRegion) {
+               boolean doesLInterfaceExist = false;
+               boolean doSubInterfacesExist = true;
+               AAIResourceUri linterfaceURI = AAIUriFactory
+                               .createResourceUri(AAIObjectPlurals.L_INTERFACE, cloudOwner, cloudRegion, tenantId, vServerId)
+                               .queryParam("interface-id", lInterface.getInterfaceId());
+               Optional<LInterfaces> queriedLInterface = getAaiClient().get(LInterfaces.class, linterfaceURI);
+               if (queriedLInterface.isPresent()) {
+                       if (queriedLInterface.get().getLInterface().size() > 1) {
+                               logger.error("Non-Unique LInterface Found stopping audit, L-Interface Id: " +lInterface.getInterfaceId());
+                               doesLInterfaceExist = false;
+                       } else {
+                               doesLInterfaceExist = true;
+                               lInterface.setInterfaceName(queriedLInterface.get().getLInterface().get(0).getInterfaceName());
+                       }
+               }
+               logger.info("l-interface id:{} name: {} exists: {}", lInterface.getInterfaceId(), lInterface.getInterfaceName(),
+                               doesLInterfaceExist);
+
+               if (doesLInterfaceExist && lInterface.getLInterfaces() != null) {
+                       doSubInterfacesExist = lInterface.getLInterfaces().getLInterface()
+                                       .stream().filter(subInterface -> !doesSubInterfaceExistinAAI(subInterface,
+                                                       lInterface.getInterfaceName(), vServerId, tenantId, cloudOwner, cloudRegion))
+                                       .findFirst().map(v -> false).orElse(true);
+               } else
+                       logger.debug("l-interface {} does not contain any sub-iterfaces", lInterface.getInterfaceId());
+
+               return doesLInterfaceExist && doSubInterfacesExist;
+       }
+
+       private boolean doesSubInterfaceExistinAAI(LInterface subInterface, String linterfaceName, String vServerId,
+                       String tenantId, String cloudOwner, String cloudRegion) {
+               logger.info("checking if sub-l-interface {} , linterfaceName: {} vserverId: {}  exists",
+                               subInterface.getInterfaceId(), linterfaceName, vServerId);
+
+               AAIResourceUri linterfaceURI = AAIUriFactory.createResourceUri(AAIObjectPlurals.SUB_L_INTERFACE, cloudOwner,
+                               cloudRegion, tenantId, vServerId, linterfaceName)
+                               .queryParam("interface-id", subInterface.getInterfaceId());
+
+               boolean doesExist = getAaiClient().exists(linterfaceURI);
+               logger.info("sub-l-interface {} exists: {}", subInterface.getInterfaceId(), doesExist);
+               return doesExist;
+       }
+}
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/HeatStackAudit.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/HeatStackAudit.java
new file mode 100644 (file)
index 0000000..7bba136
--- /dev/null
@@ -0,0 +1,199 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.adapters.audit;
+
+import java.net.URI;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.onap.aai.domain.yang.LInterface;
+import org.onap.aai.domain.yang.LInterfaces;
+import org.onap.aai.domain.yang.Vserver;
+import org.onap.so.openstack.utils.MsoHeatUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.woorea.openstack.heat.model.Link;
+import com.woorea.openstack.heat.model.Resource;
+import com.woorea.openstack.heat.model.Resources;
+import com.woorea.openstack.heat.model.Stack;
+
+@Component
+public class HeatStackAudit {
+
+       private static final String RESOURCES = "/resources";
+
+       protected static final Logger logger = LoggerFactory.getLogger(HeatStackAudit.class);
+
+       @Autowired
+       protected MsoHeatUtils heat;
+
+       @Autowired
+       protected AuditVServer auditVservers;
+
+       public boolean auditHeatStack(String cloudRegion, String cloudOwner, String tenantId, String heatStackName) {
+               try {
+                       logger.debug("Fetching Top Level Stack Information");
+                       Resources resources = heat.queryStackResources(cloudRegion, tenantId, heatStackName);
+                       List<Resource> novaResources = resources.getList().stream()
+                                       .filter(p -> "OS::Nova::Server".equals(p.getType())).collect(Collectors.toList());
+                       List<Resource> resourceGroups = resources.getList().stream()
+                                       .filter(p -> "OS::Heat::ResourceGroup".equals(p.getType()) && p.getName().contains("subinterfaces")).collect(Collectors.toList());
+                       Set<Vserver> vserversToAudit = createVserverSet(resources, novaResources);
+                       Set<Vserver> vserversWithSubInterfaces = processSubInterfaces(cloudRegion, tenantId, resourceGroups,
+                                       vserversToAudit); 
+                       return auditVservers.auditVservers(vserversWithSubInterfaces, tenantId, cloudOwner, cloudRegion);
+               } catch (Exception e) {
+                       logger.error("Error during auditing stack resources", e);
+                       return false;
+               }
+       } 
+
+       protected Set<Vserver> processSubInterfaces(String cloudRegion, String tenantId, List<Resource> resourceGroups,
+                       Set<Vserver> vServersToAudit) throws Exception {
+               for (Resource resourceGroup : resourceGroups) {
+                       processResourceGroups(cloudRegion, tenantId, vServersToAudit, resourceGroup);
+               }
+               return vServersToAudit;
+       }
+
+       protected void processResourceGroups(String cloudRegion, String tenantId, Set<Vserver> vServersWithLInterface,
+                       Resource resourceGroup) throws Exception {
+               Optional<Link> stackLink = resourceGroup.getLinks().stream().filter(link -> "nested".equals(link.getRel()))
+                               .findAny();
+               if (stackLink.isPresent()) {
+                       try {
+                               Optional<String> path = extractResourcePathFromHref(stackLink.get().getHref());
+                               if (path.isPresent()) {
+                                       logger.debug("Fetching nested Resource Stack Information");
+                                       Resources nestedResourceGroupResources = heat.executeHeatClientRequest(path.get(), cloudRegion,
+                                                       tenantId, Resources.class);
+                                       processNestedResourceGroup(cloudRegion, tenantId, vServersWithLInterface,
+                                                       nestedResourceGroupResources);
+                               } else
+                                       throw new Exception("Error finding Path from Self Link");
+                       } catch (Exception e) {
+                               logger.error("Error Parsing Link to obtain Path", e);
+                               throw new Exception("Error finding Path from Self Link");
+                       }
+
+               }
+       }
+
+       protected void processNestedResourceGroup(String cloudRegion, String tenantId, Set<Vserver> vServersWithLInterface,
+                       Resources nestedResourceGroupResources) throws Exception {
+               for (Resource resourceGroupNested : nestedResourceGroupResources) {
+                       Optional<Link> subInterfaceStackLink = resourceGroupNested.getLinks().stream()
+                                       .filter(link -> "nested".equals(link.getRel())).findAny();
+                       if (subInterfaceStackLink.isPresent()) {
+                               addSubInterface(cloudRegion, tenantId, vServersWithLInterface,subInterfaceStackLink.get());
+                       }
+               }
+       }
+
+       protected void addSubInterface(String cloudRegion, String tenantId, Set<Vserver> vServersWithLInterface, Link subInterfaceStackLink) throws Exception {
+                       Optional<String> resourcePath = extractResourcePathFromHref(subInterfaceStackLink.getHref());
+                       Optional<String> stackPath = extractStackPathFromHref(subInterfaceStackLink.getHref());
+                       if (resourcePath.isPresent() && stackPath.isPresent()) {
+                               logger.debug("Fetching nested Sub-Interface Stack Information");
+                               Stack subinterfaceStack = heat.executeHeatClientRequest(stackPath.get(), cloudRegion, tenantId, Stack.class);
+                               Resources subinterfaceResources = heat.executeHeatClientRequest(resourcePath.get(), cloudRegion, tenantId, Resources.class);
+                               if (subinterfaceStack != null) {
+                                       addSubInterfaceToVserver(vServersWithLInterface, subinterfaceStack, subinterfaceResources);
+                               }
+                       } else
+                               throw new Exception("Error finding Path from Self Link");
+               
+       }
+
+       protected void addSubInterfaceToVserver(Set<Vserver> vServersWithLInterface, Stack subinterfaceStack, Resources subinterfaceResources) throws Exception {
+               String parentNeutronPortId = (String) subinterfaceStack.getParameters().get("port_interface");
+               logger.debug("Parent neutron Port: {} on SubInterface: {}", parentNeutronPortId, subinterfaceStack.getId());
+               for (Vserver auditVserver : vServersWithLInterface)
+                       for (LInterface lInterface : auditVserver.getLInterfaces().getLInterface())
+                               
+                               if (parentNeutronPortId.equals(lInterface.getInterfaceId())) {
+                                       logger.debug("Found Parent Port on VServer: {} on Port: {}", auditVserver.getVserverId(), lInterface.getInterfaceId());
+                                       Resource contrailVm = subinterfaceResources.getList().stream().filter(resource -> "OS::ContrailV2::VirtualMachineInterface".equals(resource.getType())).findAny()
+                       .orElse(null);
+                                       if(contrailVm == null){
+                                               throw new Exception("Cannnot find Contrail Virtual Machine Interface on Stack: "+ subinterfaceStack.getId());
+                                       }
+                                       LInterface subInterface = new LInterface();
+                                       subInterface.setInterfaceId(contrailVm.getPhysicalResourceId());
+                                       
+                                       if(lInterface.getLInterfaces() == null)
+                                               lInterface.setLInterfaces(new LInterfaces());
+                                       
+                                       lInterface.getLInterfaces().getLInterface().add(subInterface);
+                               }else
+                                       logger.debug("Did Not Find Parent Port on VServer: {} Parent Port: SubInterface: {}",auditVserver.getVserverId(), 
+                                                       lInterface.getInterfaceId(),subinterfaceStack.getId());
+       }
+
+       protected Set<Vserver> createVserverSet(Resources resources, List<Resource> novaResources) {
+               Set<Vserver> vserversToAudit = new HashSet<>();
+               for (Resource novaResource : novaResources) {
+                       Vserver auditVserver = new Vserver();
+                       auditVserver.setLInterfaces(new LInterfaces());
+                       auditVserver.setVserverId(novaResource.getPhysicalResourceId());
+                       Stream<Resource> filteredNeutronNetworks = resources.getList().stream()
+                                       .filter(network -> network.getRequiredBy().contains(novaResource.getLogicalResourceId()));
+                       filteredNeutronNetworks.forEach(network -> {
+                               LInterface lInterface = new LInterface();
+                               lInterface.setInterfaceId(network.getPhysicalResourceId());
+                               auditVserver.getLInterfaces().getLInterface().add(lInterface);
+                       });
+                       vserversToAudit.add(auditVserver);
+               }
+               return vserversToAudit;
+       }
+
+       protected Optional<String> extractResourcePathFromHref(String href) {
+               URI uri;
+               try {
+                       uri = new URI(href);                    
+                       return Optional.of(uri.getPath().replaceFirst("/v\\d+", "")+RESOURCES);                 
+               } catch (Exception e) {
+                       logger.error("Error parsing URI", e);
+               }
+               return Optional.empty();
+       }
+       
+       protected Optional<String> extractStackPathFromHref(String href) {
+               URI uri;
+               try {
+                       uri = new URI(href);                    
+                       return Optional.of(uri.getPath().replaceFirst("/v\\d+", ""));                   
+               } catch (Exception e) {
+                       logger.error("Error parsing URI", e);
+               }
+               return Optional.empty();
+       }
+       
+       
+}
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/AaiClientPropertiesImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/AaiClientPropertiesImpl.java
new file mode 100644 (file)
index 0000000..c529413
--- /dev/null
@@ -0,0 +1,69 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.adapters.openstack;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.onap.so.client.aai.AAIProperties;
+import org.onap.so.client.aai.AAIVersion;
+import org.onap.so.spring.SpringContextHelper;
+import org.springframework.context.ApplicationContext;
+
+public class AaiClientPropertiesImpl implements AAIProperties {
+
+       private String aaiEndpoint;
+       private String auth;
+       private String key;
+       private static final String SYSTEM_NAME = "MSO";
+       
+       public AaiClientPropertiesImpl() {
+               ApplicationContext context = SpringContextHelper.getAppContext();
+               aaiEndpoint = context.getEnvironment().getProperty("aai.endpoint");
+               this.auth = context.getEnvironment().getProperty("aai.auth");
+               this.key = context.getEnvironment().getProperty("mso.msoKey");
+       }
+
+       @Override
+       public URL getEndpoint() throws MalformedURLException { 
+               return new URL(aaiEndpoint);
+       }
+
+       @Override
+       public String getSystemName() {
+               return SYSTEM_NAME;
+       }
+       
+       @Override
+       public AAIVersion getDefaultVersion() {
+               return AAIVersion.LATEST;
+       }
+       
+       @Override
+       public String getAuth() {
+               return this.auth;
+       }
+
+       @Override
+       public String getKey() {
+               return this.key;
+       }
+}
index a9aa50f..9408f0d 100644 (file)
@@ -31,10 +31,12 @@ import org.springframework.boot.autoconfigure.domain.EntityScan;
 import org.springframework.context.annotation.Bean;
 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 
 @SpringBootApplication(scanBasePackages = { "org.onap.so" })
 @EnableAsync
+@EnableScheduling
 @EnableJpaRepositories({ "org.onap.so.db.catalog.data.repository",
                "org.onap.so.db.request.data.repository"})
 @EntityScan({ "org.onap.so.db.catalog.beans", "org.onap.so.db.request.beans"})
diff --git a/adapters/mso-openstack-adapters/src/main/resources/META-INF/services/org.onap.so.client.RestProperties b/adapters/mso-openstack-adapters/src/main/resources/META-INF/services/org.onap.so.client.RestProperties
new file mode 100644 (file)
index 0000000..4ce4d75
--- /dev/null
@@ -0,0 +1 @@
+org.onap.so.adapters.openstack.AaiClientPropertiesImpl
\ No newline at end of file
index 8fd6d42..18084ce 100644 (file)
@@ -13,7 +13,9 @@ mso:
     core-pool-size: 50
     max-pool-size: 50
     queue-capacity: 500
-
+  workflow:
+    topics:
+      retryMultiplier: 60000
 spring:
   datasource:
     jdbc-url: jdbc:mariadb://${DB_HOST}:${DB_PORT}/catalogdb
diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/AuditStackServiceDataTest.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/AuditStackServiceDataTest.java
new file mode 100644 (file)
index 0000000..52b67b8
--- /dev/null
@@ -0,0 +1,150 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017-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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.adapters.audit;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
+
+import java.io.IOException;
+import java.util.Optional;
+
+import org.camunda.bpm.client.task.ExternalTask;
+import org.camunda.bpm.client.task.ExternalTaskService;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.onap.aai.domain.yang.LInterface;
+import org.onap.so.audit.beans.AuditInventory;
+import org.springframework.core.env.Environment;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+
+public class AuditStackServiceDataTest extends AuditStackServiceData {
+
+       @InjectMocks
+       AuditStackServiceData auditStackService = new AuditStackServiceData();
+
+       @Mock
+       HeatStackAudit heatStackAuditMock;
+
+       @Mock
+       Environment mockEnv;
+
+       @Mock
+       ExternalTask mockExternalTask;
+
+       @Mock
+       ExternalTaskService mockExternalTaskService;
+
+       AuditInventory auditInventory = new AuditInventory();
+
+       @Before
+       public void setup() {
+               auditInventory.setCloudOwner("cloudOwner");
+               auditInventory.setCloudRegion("cloudRegion");
+               auditInventory.setTenantId("tenantId");
+               auditInventory.setHeatStackName("stackName");
+               MockitoAnnotations.initMocks(this);
+               doReturn(auditInventory).when(mockExternalTask).getVariable("auditInventory");
+               doReturn("6000").when(mockEnv).getProperty("mso.workflow.topics.retryMultiplier","6000");
+               doReturn("aasdfasdf").when(mockExternalTask).getId();
+       }
+
+       @Test
+       public void execute_external_task_audit_success_Test() {
+               doReturn(true).when(heatStackAuditMock).auditHeatStack("cloudRegion", "cloudOwner", "tenantId", "stackName");
+               auditStackService.executeExternalTask(mockExternalTask, mockExternalTaskService);
+               Mockito.verify(mockExternalTaskService).complete(mockExternalTask);
+       }
+
+       @Test
+       public void execute_external_task_audit_first_failure_Test() {
+               doReturn(false).when(heatStackAuditMock).auditHeatStack("cloudRegion", "cloudOwner", "tenantId", "stackName");
+               doReturn(null).when(mockExternalTask).getRetries();
+               auditStackService.executeExternalTask(mockExternalTask, mockExternalTaskService);
+               Mockito.verify(mockExternalTaskService).handleFailure(mockExternalTask,
+                               "Unable to find all VServers and L-Interaces in A&AI",
+                               "Unable to find all VServers and L-Interaces in A&AI", 8, 10000L);
+       }
+
+       @Test
+       public void execute_external_task_audit_intermediate_failure_Test() {
+               doReturn(false).when(heatStackAuditMock).auditHeatStack("cloudRegion", "cloudOwner", "tenantId", "stackName");
+               doReturn(6).when(mockExternalTask).getRetries();
+               auditStackService.executeExternalTask(mockExternalTask, mockExternalTaskService);               
+               Mockito.verify(mockExternalTaskService).handleFailure(mockExternalTask,
+                               "Unable to find all VServers and L-Interaces in A&AI",
+                               "Unable to find all VServers and L-Interaces in A&AI", 5, 12000L);
+
+       }
+
+       @Test
+       public void execute_external_task_audit_final_failure_Test() {
+               doReturn(false).when(heatStackAuditMock).auditHeatStack("cloudRegion", "cloudOwner", "tenantId", "stackName");
+               doReturn(1).when(mockExternalTask).getRetries();
+               auditStackService.executeExternalTask(mockExternalTask, mockExternalTaskService);               
+               Mockito.verify(mockExternalTaskService).handleBpmnError(mockExternalTask,
+                               "AuditAAIInventoryFailure", "Number of Retries Exceeded auditing inventory");
+       }
+
+       @Test
+       public void retry_sequence_calculation_Test() {
+               long firstRetry = auditStackService.calculateRetryDelay(8);
+               assertEquals(6000L, firstRetry);
+               long secondRetry = auditStackService.calculateRetryDelay(7);
+               assertEquals(6000L, secondRetry);
+               long thirdRetry = auditStackService.calculateRetryDelay(6);
+               assertEquals(12000L, thirdRetry);
+               long fourthRetry = auditStackService.calculateRetryDelay(5);
+               assertEquals(18000L, fourthRetry);
+               long fifthRetry = auditStackService.calculateRetryDelay(4);
+               assertEquals(30000L, fifthRetry);
+               long sixRetry = auditStackService.calculateRetryDelay(3);
+               assertEquals(48000L, sixRetry);
+               long seventhRetry = auditStackService.calculateRetryDelay(2);
+               assertEquals(78000L, seventhRetry);
+               long eigthRetry = auditStackService.calculateRetryDelay(1);
+               assertEquals(120000L, eigthRetry);
+       }
+
+       @Test
+       public void retry_sequence_Test() {
+               long firstRetry = auditStackService.calculateRetryDelay(8);
+               assertEquals(6000L, firstRetry);
+               long secondRetry = auditStackService.calculateRetryDelay(7);
+               assertEquals(6000L, secondRetry);
+               long thirdRetry = auditStackService.calculateRetryDelay(6);
+               assertEquals(12000L, thirdRetry);
+               long fourthRetry = auditStackService.calculateRetryDelay(5);
+               assertEquals(18000L, fourthRetry);
+               long fifthRetry = auditStackService.calculateRetryDelay(4);
+               assertEquals(30000L, fifthRetry);
+               long sixRetry = auditStackService.calculateRetryDelay(3);
+               assertEquals(48000L, sixRetry);
+               long seventhRetry = auditStackService.calculateRetryDelay(2);
+               assertEquals(78000L, seventhRetry);
+               long eigthRetry = auditStackService.calculateRetryDelay(1);
+               assertEquals(120000L, eigthRetry);
+       }
+}
diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/AuditVServerTest.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/AuditVServerTest.java
new file mode 100644 (file)
index 0000000..11e5440
--- /dev/null
@@ -0,0 +1,332 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017-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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.adapters.audit;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.aai.domain.yang.LInterface;
+import org.onap.aai.domain.yang.LInterfaces;
+import org.onap.aai.domain.yang.Vserver;
+import org.onap.so.client.aai.AAIObjectPlurals;
+import org.onap.so.client.aai.AAIObjectType;
+import org.onap.so.client.aai.AAIResourcesClient;
+import org.onap.so.client.aai.entities.AAIResultWrapper;
+import org.onap.so.client.aai.entities.uri.AAIResourceUri;
+import org.onap.so.client.aai.entities.uri.AAIUriFactory;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.woorea.openstack.heat.model.Resource;
+import com.woorea.openstack.heat.model.Resources;
+
+@RunWith(MockitoJUnitRunner.Silent.class)
+public class AuditVServerTest extends AuditVServer {
+
+       private ObjectMapper objectMapper = new ObjectMapper();
+
+       @InjectMocks
+       private AuditVServer auditNova = new AuditVServer();
+
+       @Mock
+       private AAIResourcesClient aaiResourcesMock;
+
+       private String cloudOwner = "cloudOwner";
+       private String cloudRegion = "cloudRegion";
+       private String tenantId = "tenantId";
+
+       private AAIResourceUri vserverURI = AAIUriFactory.createResourceUri(AAIObjectType.VSERVER,cloudOwner, cloudRegion,
+                       tenantId, "3a4c2ca5-27b3-4ecc-98c5-06804867c4db");
+       
+       private AAIResourceUri vserverURI2 = AAIUriFactory.createResourceUri(AAIObjectType.VSERVER, cloudOwner, cloudRegion,
+                       tenantId, "3a4c2ca5-27b3-4ecc-98c5-06804867c4dz");
+
+       private AAIResourceUri ssc_1_trusted_port_0_uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.L_INTERFACE,
+                       cloudOwner, cloudRegion, tenantId, "3a4c2ca5-27b3-4ecc-98c5-06804867c4db").queryParam("interface-id", "dec8bdc7-5718-41dc-bfbb-561ff6eeb81c");
+
+       private AAIResourceUri ssc_1_avpn_port_0_uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.L_INTERFACE,
+                       cloudOwner, cloudRegion, tenantId, "3a4c2ca5-27b3-4ecc-98c5-06804867c4db").queryParam("interface-id", "1c56a24b-5f03-435a-850d-31cd4252de56");
+
+       private AAIResourceUri ssc_1_mgmt_port_1_uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.L_INTERFACE,
+                       cloudOwner, cloudRegion, tenantId, "3a4c2ca5-27b3-4ecc-98c5-06804867c4db").queryParam("interface-id", "12afcd28-929f-4d80-8a5a-0833bfd5e20b");
+
+       private AAIResourceUri ssc_1_mgmt_port_0_uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.L_INTERFACE,
+                       cloudOwner, cloudRegion, tenantId, "3a4c2ca5-27b3-4ecc-98c5-06804867c4db").queryParam("interface-id", "80baec42-ffae-425f-ad8c-3f7b2c24bfff");
+
+       private AAIResourceUri ssc_1_mis_port_0_uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.L_INTERFACE,
+                       cloudOwner, cloudRegion, tenantId, "3a4c2ca5-27b3-4ecc-98c5-06804867c4db").queryParam("interface-id", "13eddf95-4cf3-45f2-823a-2d890a6549b4");
+
+       private AAIResourceUri ssc_1_int_ha_port_0_uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.L_INTERFACE,
+                       cloudOwner, cloudRegion, tenantId, "3a4c2ca5-27b3-4ecc-98c5-06804867c4db").queryParam("interface-id", "9cab2903-70f7-44fd-b681-491d6ae2adb8");
+
+       private AAIResourceUri test_port_1_uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.L_INTERFACE,
+                       cloudOwner, cloudRegion, tenantId, "3a4c2ca5-27b3-4ecc-98c5-06804867c4dz").queryParam("interface-id", "9cab2903-70f7-44fd-b681-491d6ae2adz1");
+
+
+       private AAIResourceUri test_port_2_uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.L_INTERFACE,
+                       cloudOwner, cloudRegion, tenantId, "3a4c2ca5-27b3-4ecc-98c5-06804867c4dz").queryParam("interface-id", "9cab2903-70f7-44fd-b681-491d6ae2adz2");
+
+       
+       
+       private AAIResourceUri mis_sub_1_uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.SUB_L_INTERFACE,
+                       cloudOwner, cloudRegion, tenantId, "3a4c2ca5-27b3-4ecc-98c5-06804867c4db","interface-name").queryParam("interface-id", "f711be16-2654-4a09-b89d-0511fda20e81");
+
+       private AAIResourceUri avpn_sub_0_uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.SUB_L_INTERFACE,
+                       cloudOwner, cloudRegion, tenantId, "3a4c2ca5-27b3-4ecc-98c5-06804867c4db","interface-name").queryParam("interface-id", "0d9cd813-2ae1-46c0-9ebb-48081f6cffbb");
+
+       private AAIResourceUri avpn_sub_1_uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.SUB_L_INTERFACE,
+                       cloudOwner, cloudRegion, tenantId, "3a4c2ca5-27b3-4ecc-98c5-06804867c4db","interface-name").queryParam("interface-id", "b7019dd0-2ee9-4447-bdef-ac25676b205a");
+
+       
+
+       private Set<Vserver> vserversToAudit = new HashSet<>();
+       
+       
+       LInterface test_port_1 = new LInterface();
+       LInterface test_port_2 = new LInterface();
+       LInterface ssc_1_int_ha_port_0 = new LInterface();
+       LInterface mis_sub_interface_1 = new LInterface();
+       LInterface ssc_1_mis_port_0 = new LInterface();
+       LInterface ssc_1_mgmt_port_0 = new LInterface();
+       LInterface ssc_1_mgmt_port_1 = new LInterface();
+       LInterface avpn_sub_interface_2 = new LInterface();
+       LInterface avpn_sub_interface_1 = new LInterface();
+       LInterface ssc_1_avpn_port_0 = new LInterface();
+       LInterface ssc_1_trusted_port_0 = new LInterface();
+       
+       LInterfaces test_port_1_plural = new LInterfaces();     
+       LInterfaces test_port_2_plural = new LInterfaces();
+       LInterfaces ssc_1_int_ha_port_0_plural = new LInterfaces();
+       LInterfaces mis_sub_interface_1_plural = new LInterfaces();
+       LInterfaces ssc_1_mis_port_0_plural = new LInterfaces();
+       LInterfaces ssc_1_mgmt_port_0_plural = new LInterfaces();
+       LInterfaces ssc_1_mgmt_port_1_plural = new LInterfaces();
+       LInterfaces avpn_sub_interface_2_plural = new LInterfaces();
+       LInterfaces avpn_sub_interface_1_plural = new LInterfaces();
+       LInterfaces ssc_1_avpn_port_0_plural = new LInterfaces();
+       LInterfaces ssc_1_trusted_port_0_plural = new LInterfaces();
+       
+       
+       @Before
+       public void setup() {
+               auditNova.setAaiClient(aaiResourcesMock);
+
+               Vserver vServer1= new Vserver();
+               vServer1.setVserverId("3a4c2ca5-27b3-4ecc-98c5-06804867c4db");
+               LInterfaces vServer1Linterfaces = new LInterfaces();
+               vServer1.setLInterfaces(vServer1Linterfaces);
+               
+               ssc_1_trusted_port_0.setInterfaceId("dec8bdc7-5718-41dc-bfbb-561ff6eeb81c");
+               ssc_1_trusted_port_0.setInterfaceName("interface-name");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_trusted_port_0);
+               
+               
+               ssc_1_avpn_port_0.setInterfaceId("1c56a24b-5f03-435a-850d-31cd4252de56");
+               ssc_1_avpn_port_0.setInterfaceName("interface-name");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_avpn_port_0);
+               ssc_1_avpn_port_0.setLInterfaces(new LInterfaces());    
+               
+               
+               avpn_sub_interface_1.setInterfaceId("0d9cd813-2ae1-46c0-9ebb-48081f6cffbb");
+               ssc_1_avpn_port_0.getLInterfaces().getLInterface().add(avpn_sub_interface_1);
+               
+               
+               avpn_sub_interface_2.setInterfaceId("b7019dd0-2ee9-4447-bdef-ac25676b205a");
+               ssc_1_avpn_port_0.getLInterfaces().getLInterface().add(avpn_sub_interface_2);
+               
+               
+               ssc_1_mgmt_port_1.setInterfaceId("12afcd28-929f-4d80-8a5a-0833bfd5e20b");
+               ssc_1_mgmt_port_1.setInterfaceName("interface-name");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_mgmt_port_1);
+
+               ssc_1_mgmt_port_0.setInterfaceId("80baec42-ffae-425f-ad8c-3f7b2c24bfff");
+               ssc_1_mgmt_port_0.setInterfaceName("interface-name");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_mgmt_port_0);
+               
+       
+               ssc_1_mis_port_0.setLInterfaces(new LInterfaces());
+               ssc_1_mis_port_0.setInterfaceId("13eddf95-4cf3-45f2-823a-2d890a6549b4");
+               ssc_1_mis_port_0.setInterfaceName("interface-name");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_mis_port_0);
+               
+
+               mis_sub_interface_1.setInterfaceId("f711be16-2654-4a09-b89d-0511fda20e81");     
+               ssc_1_mis_port_0.getLInterfaces().getLInterface().add(mis_sub_interface_1);
+               
+
+               ssc_1_int_ha_port_0.setInterfaceId("9cab2903-70f7-44fd-b681-491d6ae2adb8");     
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_int_ha_port_0);
+               
+               
+               Vserver vServer2= new Vserver();
+               vServer2.setVserverId("3a4c2ca5-27b3-4ecc-98c5-06804867c4dz");
+               LInterfaces vServer2Linterfaces = new LInterfaces();
+               vServer2.setLInterfaces(vServer2Linterfaces);
+       
+               test_port_1.setInterfaceId("9cab2903-70f7-44fd-b681-491d6ae2adz1");
+               test_port_1.setInterfaceName("interface-name");
+               
+
+               test_port_2.setInterfaceId("9cab2903-70f7-44fd-b681-491d6ae2adz2");
+               test_port_2.setInterfaceName("interface-name");
+               
+               vServer2.getLInterfaces().getLInterface().add(test_port_1);
+               vServer2.getLInterfaces().getLInterface().add(test_port_2);
+               
+               vserversToAudit.add(vServer1);
+               vserversToAudit.add(vServer2);
+               
+               
+               test_port_1_plural.getLInterface().add(test_port_1);
+               test_port_2_plural.getLInterface().add(test_port_2);
+               ssc_1_int_ha_port_0_plural.getLInterface().add(ssc_1_int_ha_port_0);
+               ssc_1_mis_port_0_plural.getLInterface().add(ssc_1_mis_port_0);
+               ssc_1_mgmt_port_0_plural.getLInterface().add(ssc_1_mgmt_port_0);
+               ssc_1_mgmt_port_1_plural.getLInterface().add(ssc_1_mgmt_port_1);
+               ssc_1_avpn_port_0_plural.getLInterface().add(ssc_1_avpn_port_0);
+               ssc_1_trusted_port_0_plural.getLInterface().add(ssc_1_trusted_port_0);
+
+       } 
+       
+       @Test
+       public void audit_Vserver_Empty_HashSet() throws JsonParseException, JsonMappingException, IOException {
+               boolean exists = auditNova.auditVservers(new HashSet<Vserver>(), tenantId, cloudOwner, cloudRegion);            
+               assertEquals(false, exists);
+       }
+
+       @Test
+       public void audit_Vserver_Found_Test() throws JsonParseException, JsonMappingException, IOException {
+               doReturn(true).when(aaiResourcesMock).exists(vserverURI);
+               doReturn(true).when(aaiResourcesMock).exists(vserverURI2);
+               doReturn(Optional.of(ssc_1_trusted_port_0_plural)).when(aaiResourcesMock).get(LInterfaces.class,ssc_1_trusted_port_0_uri);
+               doReturn(Optional.of(ssc_1_avpn_port_0_plural)).when(aaiResourcesMock).get(LInterfaces.class,ssc_1_avpn_port_0_uri);
+               doReturn(Optional.of(ssc_1_mgmt_port_1_plural)).when(aaiResourcesMock).get(LInterfaces.class,ssc_1_mgmt_port_1_uri);
+               doReturn(Optional.of(ssc_1_mgmt_port_0_plural)).when(aaiResourcesMock).get(LInterfaces.class,ssc_1_mgmt_port_0_uri);
+               doReturn(Optional.of(ssc_1_mis_port_0_plural)).when(aaiResourcesMock).get(LInterfaces.class,ssc_1_mis_port_0_uri);
+               doReturn(Optional.of(ssc_1_int_ha_port_0_plural)).when(aaiResourcesMock).get(LInterfaces.class,ssc_1_int_ha_port_0_uri);
+               doReturn(Optional.of(test_port_1_plural)).when(aaiResourcesMock).get(LInterfaces.class,test_port_1_uri);
+               doReturn(Optional.of(test_port_2_plural)).when(aaiResourcesMock).get(LInterfaces.class,test_port_2_uri);
+               
+               doReturn(true).when(aaiResourcesMock).exists(mis_sub_1_uri);
+               doReturn(true).when(aaiResourcesMock).exists(avpn_sub_0_uri);
+               doReturn(true).when(aaiResourcesMock).exists(avpn_sub_1_uri);
+
+               boolean exists = auditNova.auditVservers(vserversToAudit, tenantId, cloudOwner, cloudRegion);           
+               assertEquals(true, exists);
+       }
+
+       @Test
+       public void audit_Vserver_Found_Test_Network_Not_Found()
+                       throws JsonParseException, JsonMappingException, IOException {
+               doReturn(true).when(aaiResourcesMock).exists(vserverURI);
+               doReturn(true).when(aaiResourcesMock).exists(vserverURI2);
+               doReturn(Optional.of(ssc_1_trusted_port_0_plural)).when(aaiResourcesMock).get(LInterfaces.class,ssc_1_trusted_port_0_uri);
+               doReturn(Optional.of(ssc_1_avpn_port_0_plural)).when(aaiResourcesMock).get(LInterfaces.class,ssc_1_avpn_port_0_uri);
+               doReturn(Optional.of(ssc_1_mgmt_port_1_plural)).when(aaiResourcesMock).get(LInterfaces.class,ssc_1_mgmt_port_1_uri);
+               doReturn(Optional.empty()).when(aaiResourcesMock).get(LInterfaces.class,ssc_1_mgmt_port_0_uri);
+               doReturn(Optional.of(ssc_1_mis_port_0_plural)).when(aaiResourcesMock).get(LInterfaces.class,ssc_1_mis_port_0_uri);
+               doReturn(Optional.of(ssc_1_int_ha_port_0_plural)).when(aaiResourcesMock).get(LInterfaces.class,ssc_1_int_ha_port_0_uri);
+               doReturn(Optional.of(test_port_1_plural)).when(aaiResourcesMock).get(LInterfaces.class,test_port_1_uri);
+               doReturn(Optional.of(test_port_2_plural)).when(aaiResourcesMock).get(LInterfaces.class,test_port_2_uri);
+               
+               doReturn(true).when(aaiResourcesMock).exists(mis_sub_1_uri);
+               doReturn(true).when(aaiResourcesMock).exists(avpn_sub_0_uri);
+               doReturn(true).when(aaiResourcesMock).exists(avpn_sub_1_uri);
+
+               boolean exists = auditNova.auditVservers(vserversToAudit, tenantId, cloudOwner, cloudRegion);           
+               assertEquals(false, exists);
+       }
+
+       @Test
+       public void audit_Vserver_Found_Test_Network_Not_Found_Second_Server()
+                       throws JsonParseException, JsonMappingException, IOException {
+               doReturn(true).when(aaiResourcesMock).exists(vserverURI);
+               doReturn(true).when(aaiResourcesMock).exists(vserverURI2);
+               doReturn(Optional.of(ssc_1_trusted_port_0_plural)).when(aaiResourcesMock).get(LInterface.class,ssc_1_trusted_port_0_uri);
+               doReturn(Optional.of(ssc_1_avpn_port_0_plural)).when(aaiResourcesMock).get(LInterface.class,ssc_1_avpn_port_0_uri);
+               doReturn(Optional.of(ssc_1_mgmt_port_1_plural)).when(aaiResourcesMock).get(LInterface.class,ssc_1_mgmt_port_1_uri);
+               doReturn(Optional.of(ssc_1_mgmt_port_0_plural)).when(aaiResourcesMock).get(LInterface.class,ssc_1_mgmt_port_0_uri);
+               doReturn(Optional.of(ssc_1_mis_port_0_plural)).when(aaiResourcesMock).get(LInterface.class,ssc_1_mis_port_0_uri);
+               doReturn(Optional.of(ssc_1_int_ha_port_0_plural)).when(aaiResourcesMock).get(LInterface.class,ssc_1_int_ha_port_0_uri);
+               doReturn(Optional.of(test_port_1_plural)).when(aaiResourcesMock).get(LInterface.class,test_port_1_uri);
+               doReturn(Optional.empty()).when(aaiResourcesMock).get(LInterface.class,test_port_2_uri);                
+               doReturn(true).when(aaiResourcesMock).exists(mis_sub_1_uri);
+               doReturn(true).when(aaiResourcesMock).exists(avpn_sub_0_uri);
+               doReturn(true).when(aaiResourcesMock).exists(avpn_sub_1_uri);
+               boolean exists = auditNova.auditVservers(vserversToAudit, tenantId, cloudOwner, cloudRegion);
+               assertEquals(false, exists);
+       }
+
+       @Test
+       public void audit_Vserver_Not_Found_Test() throws JsonParseException, JsonMappingException, IOException {
+               doReturn(false).when(aaiResourcesMock).exists(vserverURI);
+               doReturn(false).when(aaiResourcesMock).exists(vserverURI2);
+               boolean exists = auditNova.auditVservers(vserversToAudit, tenantId, cloudOwner, cloudRegion);           
+               assertEquals(false, exists);
+       }
+
+       @Test
+       public void audit_Vserver_first_Not_Found_Test() throws JsonParseException, JsonMappingException, IOException {
+               doReturn(false).when(aaiResourcesMock).exists(vserverURI);
+               doReturn(true).when(aaiResourcesMock).exists(vserverURI2);
+               doReturn(Optional.of(test_port_1_plural)).when(aaiResourcesMock).get(LInterface.class,test_port_1_uri);
+               doReturn(Optional.of(test_port_2_plural)).when(aaiResourcesMock).get(LInterface.class,test_port_2_uri);
+               boolean exists = auditNova.auditVservers(vserversToAudit, tenantId, cloudOwner, cloudRegion);           
+               assertEquals(false, exists);
+       }
+
+       @Test
+       public void audit_Vserver_Second_Not_Found_Test() throws JsonParseException, JsonMappingException, IOException {
+               doReturn(true).when(aaiResourcesMock).exists(vserverURI);
+               doReturn(Optional.of(ssc_1_trusted_port_0_plural)).when(aaiResourcesMock).get(LInterface.class,ssc_1_trusted_port_0_uri);
+               doReturn(Optional.of(ssc_1_avpn_port_0_plural)).when(aaiResourcesMock).get(LInterface.class,ssc_1_avpn_port_0_uri);
+               doReturn(Optional.of(ssc_1_mgmt_port_1_plural)).when(aaiResourcesMock).get(LInterface.class,ssc_1_mgmt_port_1_uri);
+               doReturn(Optional.of(ssc_1_mgmt_port_0_plural)).when(aaiResourcesMock).get(LInterface.class,ssc_1_mgmt_port_0_uri);
+               doReturn(Optional.of(ssc_1_mis_port_0_plural)).when(aaiResourcesMock).get(LInterface.class,ssc_1_mis_port_0_uri);
+               doReturn(Optional.of(ssc_1_int_ha_port_0_plural)).when(aaiResourcesMock).get(LInterface.class,ssc_1_int_ha_port_0_uri);
+               doReturn(Optional.of(test_port_1_plural)).when(aaiResourcesMock).get(LInterface.class,test_port_1_uri);
+               doReturn(Optional.of(test_port_2_plural)).when(aaiResourcesMock).get(LInterface.class,test_port_2_uri);
+               doReturn(true).when(aaiResourcesMock).exists(mis_sub_1_uri);
+               doReturn(true).when(aaiResourcesMock).exists(avpn_sub_0_uri);
+               doReturn(true).when(aaiResourcesMock).exists(avpn_sub_1_uri);
+               doReturn(false).when(aaiResourcesMock).exists(vserverURI2);
+               boolean exists = auditNova.auditVservers(vserversToAudit, tenantId, cloudOwner, cloudRegion);
+               assertEquals(false, exists);
+       }
+
+}
diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/HeatStackAuditTest.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/HeatStackAuditTest.java
new file mode 100644 (file)
index 0000000..5df5d82
--- /dev/null
@@ -0,0 +1,241 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017-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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.adapters.audit;
+
+import static com.shazam.shazamcrest.MatcherAssert.assertThat;
+import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.aai.domain.yang.LInterface;
+import org.onap.aai.domain.yang.LInterfaces;
+import org.onap.aai.domain.yang.Vserver;
+import org.onap.so.openstack.utils.MsoHeatUtils;
+import org.skyscreamer.jsonassert.JSONAssert;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.woorea.openstack.heat.model.Resource;
+import com.woorea.openstack.heat.model.Resources;
+import com.woorea.openstack.heat.model.Stack;
+
+
+@RunWith(MockitoJUnitRunner.Silent.class)
+public class HeatStackAuditTest extends HeatStackAudit {
+
+       @InjectMocks
+       private HeatStackAudit heatStackAudit = new HeatStackAudit();
+
+       @Mock
+       private MsoHeatUtils msoHeatUtilsMock;
+       
+       @Mock
+       private AuditVServer auditVserver;
+
+       private static final String cloudRegion = "cloudRegion";
+       private static final String tenantId = "tenantId";
+       
+       private Resources resources = new Resources();
+       
+       private ObjectMapper objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+       
+       private ObjectMapper stackObjectMapper = new ObjectMapper().configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
+
+       @Before
+       public void setup() throws Exception{           
+               resources= objectMapper.readValue(new File("src/test/resources/GetResources.json"), Resources.class);
+               
+       } 
+       
+       @Test
+       public void extract_proper_path_Test(){
+               Optional<String> actualResult = extractStackPathFromHref("https://orchestration.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/test_stack/f711be16-2654-4a09-b89d-0511fda20e81");
+               assertEquals("/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/test_stack/f711be16-2654-4a09-b89d-0511fda20e81", actualResult.get());
+       }
+       
+       @Test
+       public void extract_proper_resources_path_Test(){
+               Optional<String> actualResult = extractResourcePathFromHref("https://orchestration.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/test_stack/f711be16-2654-4a09-b89d-0511fda20e81");
+               assertEquals("/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/test_stack/f711be16-2654-4a09-b89d-0511fda20e81/resources", actualResult.get());
+       }
+       
+       @Test
+       public void extract_invalid_uri_Test(){
+               Optional<String> actualResult = extractStackPathFromHref("orchestrn.com:8004/v18b44d60a6f94bdcb2738f9e/stacks/test_stack/f711be16-2654-4a09-b89d-0511fda20e81");
+               assertEquals(false, actualResult.isPresent());
+       }
+
+       @Test
+       public void createVserverSet_Test() throws Exception{
+               List<Resource> novaResources = resources.getList().stream()
+                               .filter(p -> "OS::Nova::Server".equals(p.getType())).collect(Collectors.toList());
+               
+               List<Resource> resourceGroups = resources.getList().stream()
+                               .filter(p -> "OS::Heat::ResourceGroup".equals(p.getType())).collect(Collectors.toList());
+               
+               Set<Vserver> expectedVservers = new HashSet<>();
+               Vserver vServer1= new Vserver();
+               vServer1.setVserverId("92272b67-d23f-42ca-87fa-7b06a9ec81f3");
+               LInterfaces vServer1Linterfaces = new LInterfaces();
+               vServer1.setLInterfaces(vServer1Linterfaces);
+               
+               LInterface ssc_1_trusted_port_0 = new LInterface();
+               ssc_1_trusted_port_0.setInterfaceId("d2f51f82-0ec2-4581-bd1a-d2a82073e52b");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_trusted_port_0);
+               
+
+               
+               LInterface ssc_1_mgmt_port_1 = new LInterface();
+               ssc_1_mgmt_port_1.setInterfaceId("07f5b14c-147a-4d14-8c94-a9e94dbc097b");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_mgmt_port_1);
+               
+               LInterface ssc_1_mgmt_port_0 = new LInterface();
+               ssc_1_mgmt_port_0.setInterfaceId("8d93f63e-e972-48c7-ad98-b2122da47315");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_mgmt_port_0);
+               
+               LInterface ssc_1_mis_port_0 = new LInterface();
+               ssc_1_mis_port_0.setLInterfaces(new LInterfaces());
+               ssc_1_mis_port_0.setInterfaceId("0594a2f2-7ea4-42eb-abc2-48ea49677fca");        
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_mis_port_0);
+               
+               LInterface mis_sub_interface_1 = new LInterface();
+               mis_sub_interface_1.setInterfaceId("2bbfa345-33bb-495a-94b2-fb514ee1cffc");     
+               ssc_1_mis_port_0.getLInterfaces().getLInterface().add(mis_sub_interface_1);
+               
+               LInterface ssc_1_int_ha_port_0 = new LInterface();
+               ssc_1_int_ha_port_0.setInterfaceId("00bb8407-650e-48b5-b919-33b88d6f8fe3");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_int_ha_port_0);             
+               
+               
+               LInterface ssc_1_avpn_port_0 = new LInterface();
+               ssc_1_avpn_port_0.setInterfaceId("27391d94-33af-474a-927d-d409249e8fd3");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_avpn_port_0);               
+               ssc_1_avpn_port_0.setLInterfaces(new LInterfaces());            
+               
+               LInterface avpn_sub_interface_0 = new LInterface();
+               avpn_sub_interface_0.setInterfaceId("d54dfd09-75c6-4e04-b204-909455b8f933");
+               ssc_1_avpn_port_0.getLInterfaces().getLInterface().add(avpn_sub_interface_0);
+               
+               LInterface avpn_sub_interface_1 = new LInterface();
+               avpn_sub_interface_1.setInterfaceId("f7a998c0-8939-4b07-bf4a-0862e9c325e1");
+               ssc_1_avpn_port_0.getLInterfaces().getLInterface().add(avpn_sub_interface_1);
+               
+               LInterface avpn_sub_interface_2 = new LInterface();
+               avpn_sub_interface_2.setInterfaceId("621c1fea-60b8-44ee-aede-c01b8b1aaa70");
+               ssc_1_avpn_port_0.getLInterfaces().getLInterface().add(avpn_sub_interface_2);
+
+               
+               expectedVservers.add(vServer1);
+               
+               Resources avpnQueryResponse = objectMapper.readValue(new File("src/test/resources/AVPNResourceGroupResponse.json"), Resources.class);
+               doReturn(avpnQueryResponse).when(msoHeatUtilsMock).executeHeatClientRequest("/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz/31d0647a-6043-49a4-81b6-ccab29380672/resources", cloudRegion,     tenantId, Resources.class);
+               
+               Resources misQueryResponse =objectMapper.readValue(new File("src/test/resources/MISResourceGroupResponse.json"), Resources.class);
+               doReturn(misQueryResponse).when(msoHeatUtilsMock).executeHeatClientRequest("/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst/447a9b41-714e-434b-b1d0-6cce8d9f0f0c/resources", cloudRegion,       tenantId, Resources.class);
+               
+               
+               Stack misStackQuerySubInt = stackObjectMapper.readValue(new File("src/test/resources/MISSubInterface0.json"), Stack.class);
+               doReturn(misStackQuerySubInt).when(msoHeatUtilsMock).executeHeatClientRequest("/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81", cloudRegion,tenantId, Stack.class);
+               Resources misResourceQuerySubInt = objectMapper.readValue(new File("src/test/resources/MISSubInterface1Resources.json"), Resources.class);
+               doReturn(misResourceQuerySubInt).when(msoHeatUtilsMock).executeHeatClientRequest("/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81/resources", cloudRegion,tenantId, Resources.class);
+               
+               Stack avpnStackQuerySubInt1 =stackObjectMapper.readValue(new File("src/test/resources/AVPNSubInterface0.json"), Stack.class);
+               doReturn(avpnStackQuerySubInt1).when(msoHeatUtilsMock).executeHeatClientRequest("/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-1-fmn5laetg5cs/0d9cd813-2ae1-46c0-9ebb-48081f6cffbb", cloudRegion,tenantId, Stack.class);
+               Resources avpnResourceQuerySubInt1 = objectMapper.readValue(new File("src/test/resources/AVPNSubInterface0Resources.json"), Resources.class);
+               doReturn(avpnResourceQuerySubInt1).when(msoHeatUtilsMock).executeHeatClientRequest("/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-1-fmn5laetg5cs/0d9cd813-2ae1-46c0-9ebb-48081f6cffbb/resources", cloudRegion,tenantId, Resources.class);
+
+       
+               Stack avpnStackQuerySubInt2 =stackObjectMapper.readValue(new File("src/test/resources/AVPNSubInterface1.json"), Stack.class);
+               doReturn(avpnStackQuerySubInt2).when(msoHeatUtilsMock).executeHeatClientRequest("/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-0-yghihziaf36m/b7019dd0-2ee9-4447-bdef-ac25676b205a", cloudRegion,tenantId, Stack.class);
+               Resources avpnResourceQuerySubInt2 = objectMapper.readValue(new File("src/test/resources/AVPNSubInterface1Resources.json"), Resources.class);
+               doReturn(avpnResourceQuerySubInt2).when(msoHeatUtilsMock).executeHeatClientRequest("/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-0-yghihziaf36m/b7019dd0-2ee9-4447-bdef-ac25676b205a/resources", cloudRegion,tenantId, Resources.class);
+
+               Stack avpnStackQuerySubInt3 =stackObjectMapper.readValue(new File("src/test/resources/AVPNSubInterface2.json"), Stack.class);
+               doReturn(avpnStackQuerySubInt3).when(msoHeatUtilsMock).executeHeatClientRequest("/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-2-y3ndsavmsymv/bd0fc728-cbde-4301-a581-db56f494675c", cloudRegion,tenantId, Stack.class);
+               Resources avpnResourceQuerySubInt3 = objectMapper.readValue(new File("src/test/resources/AVPNSubInterface2Resources.json"), Resources.class);
+               doReturn(avpnResourceQuerySubInt3).when(msoHeatUtilsMock).executeHeatClientRequest("/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-2-y3ndsavmsymv/bd0fc728-cbde-4301-a581-db56f494675c/resources", cloudRegion,tenantId, Resources.class);
+       
+               Set<Vserver> vServersToAudit = heatStackAudit.createVserverSet(resources, novaResources);
+               Set<Vserver> vserversWithSubInterfaces = heatStackAudit.processSubInterfaces(cloudRegion,tenantId,resourceGroups, vServersToAudit);
+               
+               String actualValue = objectMapper.writeValueAsString(vserversWithSubInterfaces);
+               String expectedValue = objectMapper.writeValueAsString(expectedVservers);
+               
+               JSONAssert.assertEquals(expectedValue, actualValue, false);
+       }
+       
+
+       @Test
+       public void findInterfaceInformation_Test(){
+               List<Resource> novaResources = resources.getList().stream()
+                               .filter(p -> "OS::Nova::Server".equals(p.getType())).collect(Collectors.toList());
+               Set<Vserver> expectedVservers = new HashSet<>();
+               Vserver vServer1= new Vserver();
+               vServer1.setVserverId("92272b67-d23f-42ca-87fa-7b06a9ec81f3");
+               LInterfaces vServer1Linterfaces = new LInterfaces();
+               vServer1.setLInterfaces(vServer1Linterfaces);
+               
+               LInterface ssc_1_trusted_port_0 = new LInterface();
+               ssc_1_trusted_port_0.setInterfaceId("d2f51f82-0ec2-4581-bd1a-d2a82073e52b");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_trusted_port_0);
+               
+               LInterface ssc_1_avpn_port_0 = new LInterface();
+               ssc_1_avpn_port_0.setInterfaceId("27391d94-33af-474a-927d-d409249e8fd3");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_avpn_port_0);
+               
+               LInterface ssc_1_mgmt_port_1 = new LInterface();
+               ssc_1_mgmt_port_1.setInterfaceId("07f5b14c-147a-4d14-8c94-a9e94dbc097b");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_mgmt_port_1);
+               
+               LInterface ssc_1_mgmt_port_0 = new LInterface();
+               ssc_1_mgmt_port_0.setInterfaceId("8d93f63e-e972-48c7-ad98-b2122da47315");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_mgmt_port_0);
+               
+               LInterface ssc_1_mis_port_0 = new LInterface();
+               ssc_1_mis_port_0.setInterfaceId("0594a2f2-7ea4-42eb-abc2-48ea49677fca");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_mis_port_0);
+               
+               LInterface ssc_1_int_ha_port_0 = new LInterface();
+               ssc_1_int_ha_port_0.setInterfaceId("00bb8407-650e-48b5-b919-33b88d6f8fe3");
+               vServer1.getLInterfaces().getLInterface().add(ssc_1_int_ha_port_0);             
+               
+               expectedVservers.add(vServer1);
+       
+               Set<Vserver> actualVservers = heatStackAudit.createVserverSet(resources, novaResources);
+               
+               assertThat(actualVservers, sameBeanAs(expectedVservers));
+       }
+
+
+}
diff --git a/adapters/mso-openstack-adapters/src/test/resources/AVPNResourceGroupResponse.json b/adapters/mso-openstack-adapters/src/test/resources/AVPNResourceGroupResponse.json
new file mode 100644 (file)
index 0000000..27f971b
--- /dev/null
@@ -0,0 +1,79 @@
+{
+    "resources": [
+        {
+            "parent_resource": "ssc_1_subint_avpn_port_0_subinterfaces",
+            "resource_name": "1",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz/31d0647a-6043-49a4-81b6-ccab29380672/resources/1",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz/31d0647a-6043-49a4-81b6-ccab29380672",
+                    "rel": "stack"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-1-fmn5laetg5cs/0d9cd813-2ae1-46c0-9ebb-48081f6cffbb",
+                    "rel": "nested"
+                }
+            ],
+            "logical_resource_id": "1",
+            "resource_status_reason": "state changed",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [],
+            "resource_status": "CREATE_COMPLETE",
+            "physical_resource_id": "0d9cd813-2ae1-46c0-9ebb-48081f6cffbb",
+            "resource_type": "vlan_subinterface_ssc_avpn.yaml"
+        },
+        {
+            "parent_resource": "ssc_1_subint_avpn_port_0_subinterfaces",
+            "resource_name": "0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz/31d0647a-6043-49a4-81b6-ccab29380672/resources/0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz/31d0647a-6043-49a4-81b6-ccab29380672",
+                    "rel": "stack"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-0-yghihziaf36m/b7019dd0-2ee9-4447-bdef-ac25676b205a",
+                    "rel": "nested"
+                }
+            ],
+            "logical_resource_id": "0",
+            "resource_status_reason": "state changed",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [],
+            "resource_status": "CREATE_COMPLETE",
+            "physical_resource_id": "b7019dd0-2ee9-4447-bdef-ac25676b205a",
+            "resource_type": "vlan_subinterface_ssc_avpn.yaml"
+        },
+        {
+            "parent_resource": "ssc_1_subint_avpn_port_0_subinterfaces",
+            "resource_name": "2",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz/31d0647a-6043-49a4-81b6-ccab29380672/resources/2",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz/31d0647a-6043-49a4-81b6-ccab29380672",
+                    "rel": "stack"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-2-y3ndsavmsymv/bd0fc728-cbde-4301-a581-db56f494675c",
+                    "rel": "nested"
+                }
+            ],
+            "logical_resource_id": "2",
+            "resource_status_reason": "state changed",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [],
+            "resource_status": "CREATE_COMPLETE",
+            "physical_resource_id": "bd0fc728-cbde-4301-a581-db56f494675c",
+            "resource_type": "vlan_subinterface_ssc_avpn.yaml"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface0.json b/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface0.json
new file mode 100644 (file)
index 0000000..e0a2404
--- /dev/null
@@ -0,0 +1,41 @@
+{
+    "stack": {
+        "parent": "31d0647a-6043-49a4-81b6-ccab29380672",
+        "disable_rollback": true,
+        "description": "HOT template to instantiate a single Contrail VLAN sub-interface with associated instance IP addresses and allowed address pairs\n",
+        "links": [
+            {
+                "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-1-fmn5laetg5cs/0d9cd813-2ae1-46c0-9ebb-48081f6cffbb",
+                "rel": "self"
+            }
+        ],
+        "stack_status_reason": "Stack CREATE completed successfully",
+        "stack_name": "tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-0-yghihziaf36m",
+        "stack_user_project_id": "dfffe8b2401b45368ca6e21f19796ce1",
+        "stack_owner": "m08699",
+        "creation_time": "2019-01-23T19:34:57Z",
+        "capabilities": [],
+        "notification_topics": [],
+        "updated_time": null,
+        "timeout_mins": 120,
+        "stack_status": "CREATE_COMPLETE",
+        "parameters": {
+            "OS::project_id": "ea2d13cc98b44d60a6f94bdcb2738f9e",
+            "port_interface": "27391d94-33af-474a-927d-d409249e8fd3",
+            "OS::stack_id": "b7019dd0-2ee9-4447-bdef-ac25676b205a",
+            "OS::stack_name": "tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-0-yghihziaf36m",
+            "vip_v6_address": "2001:1890:e005:1403::",
+            "network_id": "1bc1c5fe-896f-4629-b499-a5a36ece4253,c2f4ad4a-0089-41fa-aba7-a80963def29b,70bc637c-ea0f-4452-8aca-01e90c842ff1",
+            "subinterface_name_prefix": "tsbc0005v_tsbc0005vm002_subint_untrusted_avpn",
+            "counter": "0",
+            "mac_address": "02:27:39:1d:94:33",
+            "vip_address": "12.251.1.8",
+            "vlan_tag": "101,102,103",
+            "ip_address": "12.251.1.5",
+            "ip_v6_address": "2001:1890:e005:1402:8000::"
+        },
+        "id": "0d9cd813-2ae1-46c0-9ebb-48081f6cffbb",
+        "outputs": [],
+        "template_description": "HOT template to instantiate a single Contrail VLAN sub-interface with associated instance IP addresses and allowed address pairs\n"
+    }
+}
\ No newline at end of file
diff --git a/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface0Resources.json b/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface0Resources.json
new file mode 100644 (file)
index 0000000..e0631db
--- /dev/null
@@ -0,0 +1,72 @@
+
+
+{
+    "resources": [
+        {
+            "parent_resource": "0",
+            "resource_name": "ssc_subint_mis_vmi_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81/resources/ssc_subint_mis_vmi_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_subint_mis_vmi_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [
+                "ssc_subint_mis_vmi_0_v6_ip_0",
+                "ssc_subint_mis_vmi_0_ip_0"
+            ],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "d54dfd09-75c6-4e04-b204-909455b8f933",
+            "resource_type": "OS::ContrailV2::VirtualMachineInterface"
+        },
+        {
+            "parent_resource": "0",
+            "resource_name": "ssc_subint_mis_vmi_0_v6_ip_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81/resources/ssc_subint_mis_vmi_0_v6_ip_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_subint_mis_vmi_0_v6_ip_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "e7f25707-12fd-454f-95ac-6a05cd70806f",
+            "resource_type": "OS::ContrailV2::InstanceIp"
+        },
+        {
+            "parent_resource": "0",
+            "resource_name": "ssc_subint_mis_vmi_0_ip_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81/resources/ssc_subint_mis_vmi_0_ip_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_subint_mis_vmi_0_ip_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "6d23f4d3-8f7b-42c5-bb9e-4aee5797d506",
+            "resource_type": "OS::ContrailV2::InstanceIp"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface1.json b/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface1.json
new file mode 100644 (file)
index 0000000..009533b
--- /dev/null
@@ -0,0 +1,43 @@
+
+
+{
+    "stack": {
+        "parent": "31d0647a-6043-49a4-81b6-ccab29380672",
+        "disable_rollback": true,
+        "description": "HOT template to instantiate a single Contrail VLAN sub-interface with associated instance IP addresses and allowed address pairs\n",
+        "links": [
+            {
+                "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-0-yghihziaf36m/b7019dd0-2ee9-4447-bdef-ac25676b205a",
+                "rel": "self"
+            }
+        ],
+        "stack_status_reason": "Stack CREATE completed successfully",
+        "stack_name": "tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-0-yghihziaf36m",
+        "stack_user_project_id": "dfffe8b2401b45368ca6e21f19796ce1",
+        "stack_owner": "m08699",
+        "creation_time": "2019-01-23T19:34:57Z",
+        "capabilities": [],
+        "notification_topics": [],
+        "updated_time": null,
+        "timeout_mins": 120,
+        "stack_status": "CREATE_COMPLETE",
+        "parameters": {
+            "OS::project_id": "ea2d13cc98b44d60a6f94bdcb2738f9e",
+            "port_interface": "27391d94-33af-474a-927d-d409249e8fd3",
+            "OS::stack_id": "b7019dd0-2ee9-4447-bdef-ac25676b205a",
+            "OS::stack_name": "tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-0-yghihziaf36m",
+            "vip_v6_address": "2001:1890:e005:1403::",
+            "network_id": "1bc1c5fe-896f-4629-b499-a5a36ece4253,c2f4ad4a-0089-41fa-aba7-a80963def29b,70bc637c-ea0f-4452-8aca-01e90c842ff1",
+            "subinterface_name_prefix": "tsbc0005v_tsbc0005vm002_subint_untrusted_avpn",
+            "counter": "0",
+            "mac_address": "02:27:39:1d:94:33",
+            "vip_address": "12.251.1.8",
+            "vlan_tag": "101,102,103",
+            "ip_address": "12.251.1.5",
+            "ip_v6_address": "2001:1890:e005:1402:8000::"
+        },
+        "id": "b7019dd0-2ee9-4447-bdef-ac25676b205a",
+        "outputs": [],
+        "template_description": "HOT template to instantiate a single Contrail VLAN sub-interface with associated instance IP addresses and allowed address pairs\n"
+    }
+}
\ No newline at end of file
diff --git a/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface1Resources.json b/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface1Resources.json
new file mode 100644 (file)
index 0000000..1b10f16
--- /dev/null
@@ -0,0 +1,72 @@
+
+
+{
+    "resources": [
+        {
+            "parent_resource": "0",
+            "resource_name": "ssc_subint_mis_vmi_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81/resources/ssc_subint_mis_vmi_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_subint_mis_vmi_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [
+                "ssc_subint_mis_vmi_0_v6_ip_0",
+                "ssc_subint_mis_vmi_0_ip_0"
+            ],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "f7a998c0-8939-4b07-bf4a-0862e9c325e1",
+            "resource_type": "OS::ContrailV2::VirtualMachineInterface"
+        },
+        {
+            "parent_resource": "0",
+            "resource_name": "ssc_subint_mis_vmi_0_v6_ip_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81/resources/ssc_subint_mis_vmi_0_v6_ip_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_subint_mis_vmi_0_v6_ip_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "e7f25707-12fd-454f-95ac-6a05cd70806f",
+            "resource_type": "OS::ContrailV2::InstanceIp"
+        },
+        {
+            "parent_resource": "0",
+            "resource_name": "ssc_subint_mis_vmi_0_ip_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81/resources/ssc_subint_mis_vmi_0_ip_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_subint_mis_vmi_0_ip_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "6d23f4d3-8f7b-42c5-bb9e-4aee5797d506",
+            "resource_type": "OS::ContrailV2::InstanceIp"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface2.json b/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface2.json
new file mode 100644 (file)
index 0000000..7488ee2
--- /dev/null
@@ -0,0 +1,41 @@
+{
+    "stack": {
+        "parent": "31d0647a-6043-49a4-81b6-ccab29380672",
+        "disable_rollback": true,
+        "description": "HOT template to instantiate a single Contrail VLAN sub-interface with associated instance IP addresses and allowed address pairs\n",
+        "links": [
+            {
+                "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbtsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-2-y3ndsavmsymv/bd0fc728-cbde-4301-a581-db56f494675cc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-2-y3ndsavmsymv/bd0fc728-cbde-4301-a581-db56f494675c",
+                "rel": "self"
+            }
+        ],
+        "stack_status_reason": "Stack CREATE completed successfully",
+        "stack_name": "tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-2-y3ndsavmsymv",
+        "stack_user_project_id": "dfffe8b2401b45368ca6e21f19796ce1",
+        "stack_owner": "m08699",
+        "creation_time": "2019-01-23T19:34:57Z",
+        "capabilities": [],
+        "notification_topics": [],
+        "updated_time": null,
+        "timeout_mins": 120,
+        "stack_status": "CREATE_COMPLETE",
+        "parameters": {
+            "OS::project_id": "ea2d13cc98b44d60a6f94bdcb2738f9e",
+            "port_interface": "27391d94-33af-474a-927d-d409249e8fd3",
+            "OS::stack_id": "bd0fc728-cbde-4301-a581-db56f494675c",
+            "OS::stack_name": "tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz-2-y3ndsavmsymv",
+            "vip_v6_address": "2001:1890:e005:1403::",
+            "network_id": "1bc1c5fe-896f-4629-b499-a5a36ece4253,c2f4ad4a-0089-41fa-aba7-a80963def29b,70bc637c-ea0f-4452-8aca-01e90c842ff1",
+            "subinterface_name_prefix": "tsbc0005v_tsbc0005vm002_subint_untrusted_avpn",
+            "counter": "2",
+            "mac_address": "02:27:39:1d:94:33",
+            "vip_address": "12.251.1.8",
+            "vlan_tag": "101,102,103",
+            "ip_address": "12.251.1.5",
+            "ip_v6_address": "2001:1890:e005:1402:8000::"
+        },
+        "id": "bd0fc728-cbde-4301-a581-db56f494675c",
+        "outputs": [],
+        "template_description": "HOT template to instantiate a single Contrail VLAN sub-interface with associated instance IP addresses and allowed address pairs\n"
+    }
+}
\ No newline at end of file
diff --git a/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface2Resources.json b/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface2Resources.json
new file mode 100644 (file)
index 0000000..94c7c69
--- /dev/null
@@ -0,0 +1,72 @@
+
+
+{
+    "resources": [
+        {
+            "parent_resource": "0",
+            "resource_name": "ssc_subint_mis_vmi_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81/resources/ssc_subint_mis_vmi_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_subint_mis_vmi_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [
+                "ssc_subint_mis_vmi_0_v6_ip_0",
+                "ssc_subint_mis_vmi_0_ip_0"
+            ],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "621c1fea-60b8-44ee-aede-c01b8b1aaa70",
+            "resource_type": "OS::ContrailV2::VirtualMachineInterface"
+        },
+        {
+            "parent_resource": "0",
+            "resource_name": "ssc_subint_mis_vmi_0_v6_ip_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81/resources/ssc_subint_mis_vmi_0_v6_ip_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_subint_mis_vmi_0_v6_ip_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "e7f25707-12fd-454f-95ac-6a05cd70806f",
+            "resource_type": "OS::ContrailV2::InstanceIp"
+        },
+        {
+            "parent_resource": "0",
+            "resource_name": "ssc_subint_mis_vmi_0_ip_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81/resources/ssc_subint_mis_vmi_0_ip_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_subint_mis_vmi_0_ip_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "6d23f4d3-8f7b-42c5-bb9e-4aee5797d506",
+            "resource_type": "OS::ContrailV2::InstanceIp"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/adapters/mso-openstack-adapters/src/test/resources/GetResources.json b/adapters/mso-openstack-adapters/src/test/resources/GetResources.json
new file mode 100644 (file)
index 0000000..33e282c
--- /dev/null
@@ -0,0 +1,206 @@
+{
+    "resources": [
+        {
+            "resource_name": "ssc_1_trusted_port_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34/resources/ssc_1_trusted_port_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_1_trusted_port_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:15Z",
+            "required_by": [
+                "ssc_server_1"
+            ],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "d2f51f82-0ec2-4581-bd1a-d2a82073e52b",
+            "resource_type": "OS::Neutron::Port"
+        },
+        {
+            "resource_name": "ssc_1_avpn_port_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34/resources/ssc_1_avpn_port_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_1_avpn_port_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:15Z",
+            "required_by": [
+                "ssc_1_subint_avpn_port_0_subinterfaces",
+                "ssc_server_1"
+            ],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "27391d94-33af-474a-927d-d409249e8fd3",
+            "resource_type": "OS::Neutron::Port"
+        },
+        {
+            "resource_name": "ssc_1_subint_mis_port_0_subinterfaces",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34/resources/ssc_1_subint_mis_port_0_subinterfaces",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34",
+                    "rel": "stack"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst/447a9b41-714e-434b-b1d0-6cce8d9f0f0c",
+                    "rel": "nested"
+                }
+            ],
+            "logical_resource_id": "ssc_1_subint_mis_port_0_subinterfaces",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:15Z",
+            "required_by": [],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "447a9b41-714e-434b-b1d0-6cce8d9f0f0c",
+            "resource_type": "OS::Heat::ResourceGroup"
+        },
+        {
+            "resource_name": "ssc_1_mgmt_port_1",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34/resources/ssc_1_mgmt_port_1",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_1_mgmt_port_1",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:15Z",
+            "required_by": [
+                "ssc_server_1"
+            ],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "07f5b14c-147a-4d14-8c94-a9e94dbc097b",
+            "resource_type": "OS::Neutron::Port"
+        },
+        {
+            "resource_name": "ssc_1_mgmt_port_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34/resources/ssc_1_mgmt_port_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_1_mgmt_port_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:15Z",
+            "required_by": [
+                "ssc_server_1"
+            ],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "8d93f63e-e972-48c7-ad98-b2122da47315",
+            "resource_type": "OS::Neutron::Port"
+        },
+        {
+            "resource_name": "ssc_1_mis_port_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34/resources/ssc_1_mis_port_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_1_mis_port_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:15Z",
+            "required_by": [
+                "ssc_1_subint_mis_port_0_subinterfaces",
+                "ssc_server_1"
+            ],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "0594a2f2-7ea4-42eb-abc2-48ea49677fca",
+            "resource_type": "OS::Neutron::Port"
+        },
+        {
+            "resource_name": "ssc_1_int_ha_port_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34/resources/ssc_1_int_ha_port_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_1_int_ha_port_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:15Z",
+            "required_by": [
+                "ssc_server_1"
+            ],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "00bb8407-650e-48b5-b919-33b88d6f8fe3",
+            "resource_type": "OS::Neutron::Port"
+        },
+        {
+            "resource_name": "ssc_server_1",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34/resources/ssc_server_1",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_server_1",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:15Z",
+            "required_by": [],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "92272b67-d23f-42ca-87fa-7b06a9ec81f3",
+            "resource_type": "OS::Nova::Server"
+        },
+        {
+            "resource_name": "ssc_1_subint_avpn_port_0_subinterfaces",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34/resources/ssc_1_subint_avpn_port_0_subinterfaces",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001/75e046b1-cf7d-4590-91e7-a6079f83fd34",
+                    "rel": "stack"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_avpn_port_0_subinterfaces-dtmxjmny7yjz/31d0647a-6043-49a4-81b6-ccab29380672",
+                    "rel": "nested"
+                }
+            ],
+            "logical_resource_id": "ssc_1_subint_avpn_port_0_subinterfaces",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:15Z",
+            "required_by": [],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "31d0647a-6043-49a4-81b6-ccab29380672",
+            "resource_type": "OS::Heat::ResourceGroup"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/adapters/mso-openstack-adapters/src/test/resources/MISResourceGroupResponse.json b/adapters/mso-openstack-adapters/src/test/resources/MISResourceGroupResponse.json
new file mode 100644 (file)
index 0000000..2350138
--- /dev/null
@@ -0,0 +1,31 @@
+
+
+{
+    "resources": [
+        {
+            "parent_resource": "ssc_1_subint_mis_port_0_subinterfaces",
+            "resource_name": "0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst/447a9b41-714e-434b-b1d0-6cce8d9f0f0c/resources/0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst/447a9b41-714e-434b-b1d0-6cce8d9f0f0c",
+                    "rel": "stack"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81",
+                    "rel": "nested"
+                }
+            ],
+            "logical_resource_id": "0",
+            "resource_status_reason": "state changed",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [],
+            "resource_status": "CREATE_COMPLETE",
+            "physical_resource_id": "f711be16-2654-4a09-b89d-0511fda20e81",
+            "resource_type": "vlan_subinterface_ssc_mis.yaml"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/adapters/mso-openstack-adapters/src/test/resources/MISSubInterface0.json b/adapters/mso-openstack-adapters/src/test/resources/MISSubInterface0.json
new file mode 100644 (file)
index 0000000..d879b3b
--- /dev/null
@@ -0,0 +1,41 @@
+{
+    "stack": {
+        "parent": "447a9b41-714e-434b-b1d0-6cce8d9f0f0c",
+        "disable_rollback": true,
+        "description": "HOT template to instantiate a single Contrail VLAN sub-interface with associated instance IP addresses and allowed address pairs\n",
+        "links": [
+            {
+                "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81",
+                "rel": "self"
+            }
+        ],
+        "stack_status_reason": "Stack CREATE completed successfully",
+        "stack_name": "tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y",
+        "stack_user_project_id": "dfffe8b2401b45368ca6e21f19796ce1",
+        "stack_owner": "m08699",
+        "creation_time": "2019-01-23T19:34:56Z",
+        "capabilities": [],
+        "notification_topics": [],
+        "updated_time": null,
+        "timeout_mins": 120,
+        "stack_status": "CREATE_COMPLETE",
+        "parameters": {
+            "OS::project_id": "ea2d13cc98b44d60a6f94bdcb2738f9e",
+            "port_interface": "0594a2f2-7ea4-42eb-abc2-48ea49677fca",
+            "OS::stack_id": "f711be16-2654-4a09-b89d-0511fda20e81",
+            "OS::stack_name": "tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y",
+            "vip_v6_address": "2001:1890:1001:4a32::3",
+            "network_id": "8be20e92-68d6-4aec-ae66-0fc0fc933546",
+            "subinterface_name_prefix": "tsbc0005v_tsbc0005vm002_subint_untrusted_mis",
+            "counter": "0",
+            "mac_address": "02:05:94:a2:f2:7e",
+            "vip_address": "32.68.12.91",
+            "vlan_tag": "81",
+            "ip_address": "32.68.12.92",
+            "ip_v6_address": "2001:1890:1001:4a32::4"
+        },
+        "id": "f711be16-2654-4a09-b89d-0511fda20e81",
+        "outputs": [],
+        "template_description": "HOT template to instantiate a single Contrail VLAN sub-interface with associated instance IP addresses and allowed address pairs\n"
+    }
+}
\ No newline at end of file
diff --git a/adapters/mso-openstack-adapters/src/test/resources/MISSubInterface1Resources.json b/adapters/mso-openstack-adapters/src/test/resources/MISSubInterface1Resources.json
new file mode 100644 (file)
index 0000000..5fa2795
--- /dev/null
@@ -0,0 +1,70 @@
+{
+    "resources": [
+        {
+            "parent_resource": "0",
+            "resource_name": "ssc_subint_mis_vmi_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81/resources/ssc_subint_mis_vmi_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_subint_mis_vmi_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [
+                "ssc_subint_mis_vmi_0_v6_ip_0",
+                "ssc_subint_mis_vmi_0_ip_0"
+            ],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "2bbfa345-33bb-495a-94b2-fb514ee1cffc",
+            "resource_type": "OS::ContrailV2::VirtualMachineInterface"
+        },
+        {
+            "parent_resource": "0",
+            "resource_name": "ssc_subint_mis_vmi_0_v6_ip_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81/resources/ssc_subint_mis_vmi_0_v6_ip_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_subint_mis_vmi_0_v6_ip_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "e7f25707-12fd-454f-95ac-6a05cd70806f",
+            "resource_type": "OS::ContrailV2::InstanceIp"
+        },
+        {
+            "parent_resource": "0",
+            "resource_name": "ssc_subint_mis_vmi_0_ip_0",
+            "links": [
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81/resources/ssc_subint_mis_vmi_0_ip_0",
+                    "rel": "self"
+                },
+                {
+                    "href": "https://orchestration-aic.dyh3b.cci.att.com:8004/v1/ea2d13cc98b44d60a6f94bdcb2738f9e/stacks/tsbc0005vm002ssc001-ssc_1_subint_mis_port_0_subinterfaces-hlzdigtimzst-0-upfi5nhurk7y/f711be16-2654-4a09-b89d-0511fda20e81",
+                    "rel": "stack"
+                }
+            ],
+            "logical_resource_id": "ssc_subint_mis_vmi_0_ip_0",
+            "resource_status": "CREATE_COMPLETE",
+            "updated_time": "2019-01-23T19:34:56Z",
+            "required_by": [],
+            "resource_status_reason": "state changed",
+            "physical_resource_id": "6d23f4d3-8f7b-42c5-bb9e-4aee5797d506",
+            "resource_type": "OS::ContrailV2::InstanceIp"
+        }
+    ]
+}
\ No newline at end of file
index 0611e62..5d6eee7 100644 (file)
     <appender-ref ref="STDOUT" />
   </logger> 
   
-    <logger name="org.onap" level="${so.log.level:-DEBUG}" additivity="false">
+ <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> 
 
index fe41aae..ebc705c 100644 (file)
@@ -1054,7 +1054,21 @@ public class ToscaResourceInstaller {
                        ToscaResourceStructure toscaResourceStructure, HeatTemplate heatTemplate, String aicMax, String aicMin,Service service) {
                
                NetworkResourceCustomization networkResourceCustomization=networkCustomizationRepo.findOneByModelCustomizationUUID(networkNodeTemplate.getMetaData().getValue(SdcPropertyNames.PROPERTY_NAME_CUSTOMIZATIONUUID));
-                               if(networkResourceCustomization==null){
+                               
+               boolean networkUUIDsMatch = true;
+               // Check to make sure the NetworkResourceUUID on the Customization record matches the NetworkResourceUUID from the distribution.  
+               // If not we'll update the Customization record with latest from the distribution
+               if(networkResourceCustomization != null){
+                       String existingNetworkModelUUID = networkResourceCustomization.getNetworkResource().getModelUUID();
+                       String latestNetworkModelUUID = networkNodeTemplate.getMetaData().getValue(SdcPropertyNames.PROPERTY_NAME_UUID);
+                       
+                       if(!existingNetworkModelUUID.equals(latestNetworkModelUUID)){
+                               networkUUIDsMatch = false;
+                       }
+               
+               }
+
+               if(networkResourceCustomization==null || !networkUUIDsMatch){
                        networkResourceCustomization = createNetworkResourceCustomization(networkNodeTemplate,
                                        toscaResourceStructure);
                                        
@@ -1066,7 +1080,8 @@ public class ToscaResourceInstaller {
 
                                        networkResource.addNetworkResourceCustomization(networkResourceCustomization);          
                                        networkResourceCustomization.setNetworkResource(networkResource);
-                               }
+               }
+               
                return networkResourceCustomization;
        }
        
index d2e0b07..b210b5e 100644 (file)
@@ -40,18 +40,19 @@ import org.springframework.stereotype.Component;
 
 @Component
 public class ExecuteBuildingBlockRainyDay {
-       
-       private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, ExecuteBuildingBlockRainyDay.class);
+
+       private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL,
+                       ExecuteBuildingBlockRainyDay.class);
        public static final String HANDLING_CODE = "handlingCode";
-       
+
        @Autowired
        private CatalogDbClient catalogDbClient;
        @Autowired
        private RequestsDbClient requestDbclient;
        private static final String ASTERISK = "*";
-       
+
        @Autowired
-    private Environment environment;
+       private Environment environment;
        protected String retryDurationPath = "mso.rainyDay.retryDurationMultiplier";
        protected String defaultCode = "mso.rainyDay.defaultCode";
 
@@ -67,7 +68,7 @@ public class ExecuteBuildingBlockRainyDay {
                        throw new BpmnError("Unknown error incrementing retry counter");
                }
        }
-       
+
        public void queryRainyDayTable(DelegateExecution execution, boolean primaryPolicy) {
                try {
                        ExecuteBuildingBlock ebb = (ExecuteBuildingBlock) execution.getVariable("buildingBlock");
@@ -79,18 +80,20 @@ public class ExecuteBuildingBlockRainyDay {
                        boolean aLaCarte = (boolean) execution.getVariable("aLaCarte");
                        boolean suppressRollback = (boolean) execution.getVariable("suppressRollback");
                        String handlingCode = "";
-                       if(suppressRollback){
+                       if (suppressRollback) {
                                handlingCode = "Abort";
-                       }else{
+                       } else {
                                try {
-                                       serviceType = gBBInput.getCustomer().getServiceSubscription().getServiceInstances().get(0).getModelInfoServiceInstance().getServiceType();
+                                       serviceType = gBBInput.getCustomer().getServiceSubscription().getServiceInstances().get(0)
+                                                       .getModelInfoServiceInstance().getServiceType();
                                } catch (Exception ex) {
                                        // keep default serviceType value
                                }
                                String vnfType = ASTERISK;
                                try {
-                                       for(GenericVnf vnf : gBBInput.getCustomer().getServiceSubscription().getServiceInstances().get(0).getVnfs()) {
-                                               if(vnf.getVnfId().equalsIgnoreCase(lookupKeyMap.get(ResourceKey.GENERIC_VNF_ID))) {
+                                       for (GenericVnf vnf : gBBInput.getCustomer().getServiceSubscription().getServiceInstances().get(0)
+                                                       .getVnfs()) {
+                                               if (vnf.getVnfId().equalsIgnoreCase(lookupKeyMap.get(ResourceKey.GENERIC_VNF_ID))) {
                                                        vnfType = vnf.getVnfType();
                                                }
                                        }
@@ -104,58 +107,78 @@ public class ExecuteBuildingBlockRainyDay {
                                } catch (Exception ex) {
                                        // keep default errorCode value
                                }
+                               try {
+                                       errorCode = "" + (String) execution.getVariable("WorkflowExceptionCode");
+                               } catch (Exception ex) {
+                                       // keep default errorCode value
+                               }
+
                                String workStep = ASTERISK;
                                try {
                                        workStep = workflowException.getWorkStep();
                                } catch (Exception ex) {
                                        // keep default workStep value
                                }
-                               //Extract error data to be returned to WorkflowAction
-                               execution.setVariable("WorkflowExceptionErrorMessage", workflowException.getErrorMessage());
+                               
+                               try {
+                                       // Extract error data to be returned to WorkflowAction
+                                       execution.setVariable("WorkflowExceptionErrorMessage", workflowException.getErrorMessage());
+                               } catch (Exception e) {
+                                       msoLogger.error("No WorkflowException Found",e);
+                               }
                                RainyDayHandlerStatus rainyDayHandlerStatus;
-                               rainyDayHandlerStatus = catalogDbClient.getRainyDayHandlerStatusByFlowNameAndServiceTypeAndVnfTypeAndErrorCodeAndWorkStep(bbName,serviceType,vnfType,errorCode,workStep);
-                               if(rainyDayHandlerStatus==null){
-                                       rainyDayHandlerStatus = catalogDbClient.getRainyDayHandlerStatusByFlowNameAndServiceTypeAndVnfTypeAndErrorCodeAndWorkStep(bbName,ASTERISK,ASTERISK,ASTERISK,ASTERISK);
-                                       if(rainyDayHandlerStatus==null){
+                               rainyDayHandlerStatus = catalogDbClient
+                                               .getRainyDayHandlerStatusByFlowNameAndServiceTypeAndVnfTypeAndErrorCodeAndWorkStep(bbName,
+                                                               serviceType, vnfType, errorCode, workStep);
+                               if (rainyDayHandlerStatus == null) {
+                                       rainyDayHandlerStatus = catalogDbClient
+                                                       .getRainyDayHandlerStatusByFlowNameAndServiceTypeAndVnfTypeAndErrorCodeAndWorkStep(bbName,
+                                                                       ASTERISK, ASTERISK, errorCode, ASTERISK);
+                               }
+                               
+                               if (rainyDayHandlerStatus == null) {
+                                       rainyDayHandlerStatus = catalogDbClient
+                                                       .getRainyDayHandlerStatusByFlowNameAndServiceTypeAndVnfTypeAndErrorCodeAndWorkStep(bbName,
+                                                                       ASTERISK, ASTERISK, ASTERISK, ASTERISK);
+                                       if (rainyDayHandlerStatus == null) {
                                                handlingCode = "Abort";
-                                       }else{
-                                               if(primaryPolicy){
+                                       } else {
+                                               if (primaryPolicy) {
                                                        handlingCode = rainyDayHandlerStatus.getPolicy();
-                                               }else{
+                                               } else {
                                                        handlingCode = rainyDayHandlerStatus.getSecondaryPolicy();
                                                }
                                        }
-                               }else{
-                                       if(primaryPolicy){
+                               } else {
+                                       if (primaryPolicy) {
                                                handlingCode = rainyDayHandlerStatus.getPolicy();
-                                       }else{
+                                       } else {
                                                handlingCode = rainyDayHandlerStatus.getSecondaryPolicy();
                                        }
                                }
-                               if(!primaryPolicy){
-                                       try{
+                               if (!primaryPolicy) {
+                                       try {
                                                InfraActiveRequests request = requestDbclient.getInfraActiveRequestbyRequestId(requestId);
                                                request.setRetryStatusMessage("Retries have been exhausted.");
                                                requestDbclient.updateInfraActiveRequests(request);
-                                       } catch(Exception ex){
-                                               msoLogger.debug(ex.toString());
-                                               msoLogger.error("Failed to update Request Db Infra Active Requests with Retry Status");
+                                       } catch (Exception ex) {
+                                               msoLogger.error("Failed to update Request Db Infra Active Requests with Retry Status",ex);
                                        }
                                }
-                               if(handlingCode.equals("RollbackToAssigned")&&!aLaCarte){
+                               if (handlingCode.equals("RollbackToAssigned") && !aLaCarte) {
                                        handlingCode = "Rollback";
                                }
                        }
                        msoLogger.debug("RainyDayHandler Status Code is: " + handlingCode);
                        execution.setVariable(HANDLING_CODE, handlingCode);
                } catch (Exception e) {
-                       msoLogger.error("Failed to determine RainyDayHandler Status. Seting handlingCode = Abort");
+                       msoLogger.error("Failed to determine RainyDayHandler Status. Seting handlingCode = Abort", e);
                        String code = this.environment.getProperty(defaultCode);
                        execution.setVariable(HANDLING_CODE, code);
                }
        }
-       
-       public void setHandlingStatusSuccess(DelegateExecution execution){
+
+       public void setHandlingStatusSuccess(DelegateExecution execution) {
                execution.setVariable(HANDLING_CODE, "Success");
        }
 }
index adffee6..459ef66 100644 (file)
@@ -78,7 +78,6 @@ public class ExceptionBuilder {
                                        break;
                                }
                        }
-
                        msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, msg.toString());
                        execution.setVariable(errorVariable, exception.getMessage());
                } catch (Exception ex){
@@ -108,6 +107,11 @@ public class ExceptionBuilder {
                msoLogger.info("Throwing MSOWorkflowException");
                throw new BpmnError("MSOWorkflowException");
        }
+       
+       public void buildAndThrowWorkflowException(DelegateExecution execution, String errorCode, String errorMessage) {
+               execution.setVariable("WorkflowExceptionErrorMessage", errorMessage);
+               throw new BpmnError(errorCode,errorMessage);
+       }
 
        public String getProcessKey(DelegateExecution execution) {
                String testKey = (String) execution.getVariable("testProcessKey");
index cb5683d..868aabf 100644 (file)
@@ -93,7 +93,7 @@ public class ExecuteBuildlingBlockRainyDayTest extends BaseTest {
                vnf.setVnfType("vnft1");
                delegateExecution.setVariable("aLaCarte", true);                
                delegateExecution.setVariable("suppressRollback", false);
-
+               delegateExecution.setVariable("WorkflowExceptionCode", "7000");
                RainyDayHandlerStatus rainyDayHandlerStatus = new RainyDayHandlerStatus();
                rainyDayHandlerStatus.setErrorCode("7000");
                rainyDayHandlerStatus.setFlowName("AssignServiceInstanceBB");
@@ -116,7 +116,7 @@ public class ExecuteBuildlingBlockRainyDayTest extends BaseTest {
                vnf.setVnfType("vnft1");
                delegateExecution.setVariable("aLaCarte", true);
                delegateExecution.setVariable("suppressRollback", false);
-               
+               delegateExecution.setVariable("WorkflowExceptionCode", ASTERISK);
                RainyDayHandlerStatus rainyDayHandlerStatus = new RainyDayHandlerStatus();
                rainyDayHandlerStatus.setErrorCode(ASTERISK);
                rainyDayHandlerStatus.setFlowName("AssignServiceInstanceBB");
@@ -164,7 +164,7 @@ public class ExecuteBuildlingBlockRainyDayTest extends BaseTest {
                vnf.setVnfType("vnft1");
                delegateExecution.setVariable("aLaCarte", true);
                delegateExecution.setVariable("suppressRollback", false);
-               
+               delegateExecution.setVariable("WorkflowExceptionCode", "7000");
                RainyDayHandlerStatus rainyDayHandlerStatus = new RainyDayHandlerStatus();
                rainyDayHandlerStatus.setErrorCode("7000");
                rainyDayHandlerStatus.setFlowName("AssignServiceInstanceBB");
@@ -188,7 +188,7 @@ public class ExecuteBuildlingBlockRainyDayTest extends BaseTest {
                vnf.setVnfType("vnft1");
                delegateExecution.setVariable("aLaCarte", false);
                delegateExecution.setVariable("suppressRollback", false);
-               
+               delegateExecution.setVariable("WorkflowExceptionCode", "7000");
                RainyDayHandlerStatus rainyDayHandlerStatus = new RainyDayHandlerStatus();
                rainyDayHandlerStatus.setErrorCode("7000");
                rainyDayHandlerStatus.setFlowName("AssignServiceInstanceBB");
@@ -212,7 +212,7 @@ public class ExecuteBuildlingBlockRainyDayTest extends BaseTest {
                vnf.setVnfType("vnft1");
                delegateExecution.setVariable("aLaCarte", true);
                delegateExecution.setVariable("suppressRollback", false);
-               
+               delegateExecution.setVariable("WorkflowExceptionCode", "7000");
                RainyDayHandlerStatus rainyDayHandlerStatus = new RainyDayHandlerStatus();
                rainyDayHandlerStatus.setErrorCode("7000");
                rainyDayHandlerStatus.setFlowName("AssignServiceInstanceBB");
index 203988a..829fc12 100644 (file)
@@ -2,7 +2,9 @@ server:
   port: 8080  
   tomcat:
     max-threads: 50
-
+mso:
+  infra:
+    auditInventory: true
 spring: 
   datasource:
      driver-class-name: org.mariadb.jdbc.Driver 
index 4fe02ee..0971a9d 100644 (file)
                        <artifactId>mariaDB4j</artifactId>
                        <version>2.2.3</version>
                        <scope>test</scope>
-               </dependency>           
+               </dependency>   
+
        </dependencies>
 </project>
index 3670676..fd24be1 100644 (file)
@@ -1,16 +1,17 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="2.0.3">
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.7.1">
   <bpmn:process id="ActivateVfModuleBB" name="ActivateVfModuleBB" isExecutable="true">
     <bpmn:startEvent id="ActivateVfModuleBB_Start">
       <bpmn:outgoing>SequenceFlow_0ieafii</bpmn:outgoing>
     </bpmn:startEvent>
-    <bpmn:sequenceFlow id="SequenceFlow_0ieafii" sourceRef="ActivateVfModuleBB_Start" targetRef="SetTimerDuration" />
+    <bpmn:sequenceFlow id="SequenceFlow_0ieafii" sourceRef="ActivateVfModuleBB_Start" targetRef="CheckAuditVariable" />
     <bpmn:endEvent id="ActivateVfModuleBB_End">
       <bpmn:incoming>SequenceFlow_0xsp0pv</bpmn:incoming>
     </bpmn:endEvent>
     <bpmn:serviceTask id="ActivateVfModule" name="&#10;SDNC&#10;Activate&#10;(vf module)&#10;" camunda:expression="${SDNCActivateTasks.activateVfModule(InjectExecution.execute(execution, execution.getVariable(&#34;gBuildingBlockExecution&#34;)))}">
-      <bpmn:incoming>SequenceFlow_0e44ywc</bpmn:incoming>
-      <bpmn:outgoing>SequenceFlow_1yzril6</bpmn:outgoing>
+      <bpmn:incoming>SequenceFlow_07ybdik</bpmn:incoming>
+      <bpmn:incoming>SequenceFlow_0ee42yq</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_1a495wm</bpmn:outgoing>
     </bpmn:serviceTask>
     <bpmn:serviceTask id="UpdateVfModuleActiveStatus" name="&#10;AAI&#10;Update&#10;(vf module)&#10;" camunda:expression="${AAIUpdateTasks.updateOrchestrationStatusActivateVfModule(InjectExecution.execute(execution, execution.getVariable(&#34;gBuildingBlockExecution&#34;)))}">
       <bpmn:incoming>SequenceFlow_1j4x1ej</bpmn:incoming>
         <camunda:out source="WorkflowException" target="WorkflowException" />
         <camunda:in source="mso-request-id" target="mso-request-id" />
       </bpmn:extensionElements>
-      <bpmn:incoming>SequenceFlow_1yzril6</bpmn:incoming>
+      <bpmn:incoming>SequenceFlow_1a495wm</bpmn:incoming>
       <bpmn:outgoing>SequenceFlow_1j4x1ej</bpmn:outgoing>
     </bpmn:callActivity>
+    <bpmn:sequenceFlow id="SequenceFlow_1a495wm" sourceRef="ActivateVfModule" targetRef="CallActivity_sdncHandler" />
     <bpmn:sequenceFlow id="SequenceFlow_1j4x1ej" sourceRef="CallActivity_sdncHandler" targetRef="UpdateVfModuleActiveStatus" />
-    <bpmn:serviceTask id="SetTimerDuration" name="Set Timer Duration" camunda:expression="${ActivateVfModule.setTimerDuration(InjectExecution.execute(execution, execution.getVariable(&#34;gBuildingBlockExecution&#34;)))}">
+    <bpmn:sequenceFlow id="SequenceFlow_0xndboi" sourceRef="Setup_AAI_Inventory_Audit" targetRef="Audit_AAI_Inventory" />
+    <bpmn:serviceTask id="Setup_AAI_Inventory_Audit" name="Setup Inventory Audit Variable" camunda:expression="${AuditTasks.setupAuditVariable(InjectExecution.execute(execution, execution.getVariable(&#34;gBuildingBlockExecution&#34;)))}">
+      <bpmn:incoming>SequenceFlow_0ghzwlo</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_0xndboi</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:serviceTask id="Audit_AAI_Inventory" name="Validate A&#38;AI Inventory" camunda:type="external" camunda:topic="InventoryAudit">
+      <bpmn:incoming>SequenceFlow_0xndboi</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_0ee42yq</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:boundaryEvent id="BoundaryEvent_1nb1hw4" attachedToRef="Audit_AAI_Inventory">
+      <bpmn:outgoing>SequenceFlow_1t99ceh</bpmn:outgoing>
+      <bpmn:errorEventDefinition />
+    </bpmn:boundaryEvent>
+    <bpmn:sequenceFlow id="SequenceFlow_1t99ceh" sourceRef="BoundaryEvent_1nb1hw4" targetRef="Task_0swpw3v" />
+    <bpmn:serviceTask id="Task_0swpw3v" name="Throw Exception" camunda:expression="${ExceptionBuilder.buildAndThrowWorkflowException(execution, &#34;AuditAAIInventoryFailure&#34;, &#34;Error Auditing Cloud Inventory in A&#38;AI&#34;)}" camunda:resultVariable="ExceptionBuilder">
+      <bpmn:incoming>SequenceFlow_1t99ceh</bpmn:incoming>
+    </bpmn:serviceTask>
+    <bpmn:exclusiveGateway id="ExclusiveGateway_1v8bmbu" default="SequenceFlow_07ybdik">
+      <bpmn:incoming>SequenceFlow_1xqyur9</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_07ybdik</bpmn:outgoing>
+      <bpmn:outgoing>SequenceFlow_0ghzwlo</bpmn:outgoing>
+    </bpmn:exclusiveGateway>
+    <bpmn:sequenceFlow id="SequenceFlow_07ybdik" sourceRef="ExclusiveGateway_1v8bmbu" targetRef="ActivateVfModule" />
+    <bpmn:sequenceFlow id="SequenceFlow_0ghzwlo" sourceRef="ExclusiveGateway_1v8bmbu" targetRef="Setup_AAI_Inventory_Audit">
+      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression"><![CDATA[${execution.getVariable("auditInventoryNeeded").equals("true")}]]></bpmn:conditionExpression>
+    </bpmn:sequenceFlow>
+    <bpmn:sequenceFlow id="SequenceFlow_0ee42yq" sourceRef="Audit_AAI_Inventory" targetRef="ActivateVfModule" />
+    <bpmn:serviceTask id="CheckAuditVariable" name="Check Audit Variable" camunda:expression="${AuditTasks.isAuditNeeded(InjectExecution.execute(execution, execution.getVariable(&#34;gBuildingBlockExecution&#34;)))}">
       <bpmn:incoming>SequenceFlow_0ieafii</bpmn:incoming>
-      <bpmn:outgoing>SequenceFlow_0qc2sao</bpmn:outgoing>
+      <bpmn:outgoing>SequenceFlow_1xqyur9</bpmn:outgoing>
     </bpmn:serviceTask>
-    <bpmn:intermediateCatchEvent id="Timer" name="Timer">
-      <bpmn:incoming>SequenceFlow_0qc2sao</bpmn:incoming>
-      <bpmn:outgoing>SequenceFlow_0e44ywc</bpmn:outgoing>
-      <bpmn:timerEventDefinition>
-        <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">${execution.getVariable("vfModuleActivateTimerDuration")}</bpmn:timeDuration>
-      </bpmn:timerEventDefinition>
-    </bpmn:intermediateCatchEvent>
-    <bpmn:sequenceFlow id="SequenceFlow_0qc2sao" sourceRef="SetTimerDuration" targetRef="Timer" />
-    <bpmn:sequenceFlow id="SequenceFlow_0e44ywc" sourceRef="Timer" targetRef="ActivateVfModule" />
-    <bpmn:sequenceFlow id="SequenceFlow_1yzril6" sourceRef="ActivateVfModule" targetRef="CallActivity_sdncHandler" />
+    <bpmn:sequenceFlow id="SequenceFlow_1xqyur9" sourceRef="CheckAuditVariable" targetRef="ExclusiveGateway_1v8bmbu" />
   </bpmn:process>
-  <bpmn:error id="Error_0q258vt" name="gDelegateError" errorCode="7000" />
+  <bpmn:error id="Error_0q258vt" errorCode="7000" />
   <bpmndi:BPMNDiagram id="BPMNDiagram_1">
     <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="ActivateVfModuleBB">
       <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="ActivateVfModuleBB_Start">
-        <dc:Bounds x="173" y="102" width="36" height="36" />
+        <dc:Bounds x="73" y="102" width="36" height="36" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="179" y="138" width="24" height="12" />
+          <dc:Bounds x="46" y="138" width="90" height="12" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNEdge id="SequenceFlow_0ieafii_di" bpmnElement="SequenceFlow_0ieafii">
-        <di:waypoint x="209" y="120" />
-        <di:waypoint x="274" y="120" />
+        <di:waypoint xsi:type="dc:Point" x="109" y="120" />
+        <di:waypoint xsi:type="dc:Point" x="161" y="120" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="190.5" y="99" width="90" height="12" />
+          <dc:Bounds x="90" y="99" width="90" height="12" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNShape id="EndEvent_1v967li_di" bpmnElement="ActivateVfModuleBB_End">
-        <dc:Bounds x="956" y="102" width="36" height="36" />
+        <dc:Bounds x="1104" y="102" width="36" height="36" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="710" y="142" width="90" height="12" />
+          <dc:Bounds x="935" y="142" width="90" height="12" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape id="ServiceTask_0hawa84_di" bpmnElement="ActivateVfModule">
-        <dc:Bounds x="490" y="80" width="100" height="80" />
+        <dc:Bounds x="539" y="80" width="100" height="80" />
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape id="ServiceTask_175e9ul_di" bpmnElement="UpdateVfModuleActiveStatus">
-        <dc:Bounds x="770" y="80" width="100" height="80" />
+        <dc:Bounds x="952" y="80" width="100" height="80" />
       </bpmndi:BPMNShape>
       <bpmndi:BPMNEdge id="SequenceFlow_0xsp0pv_di" bpmnElement="SequenceFlow_0xsp0pv">
-        <di:waypoint x="870" y="120" />
-        <di:waypoint x="956" y="120" />
+        <di:waypoint xsi:type="dc:Point" x="1052" y="120" />
+        <di:waypoint xsi:type="dc:Point" x="1104" y="120" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="673" y="99" width="90" height="12" />
+          <dc:Bounds x="1033" y="99" width="90" height="12" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNShape id="CallActivity_03jkesd_di" bpmnElement="CallActivity_sdncHandler">
-        <dc:Bounds x="639" y="80" width="100" height="80" />
+        <dc:Bounds x="794" y="80" width="100" height="80" />
       </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_1a495wm_di" bpmnElement="SequenceFlow_1a495wm">
+        <di:waypoint xsi:type="dc:Point" x="639" y="120" />
+        <di:waypoint xsi:type="dc:Point" x="794" y="120" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="671.5" y="99" width="90" height="12" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
       <bpmndi:BPMNEdge id="SequenceFlow_1j4x1ej_di" bpmnElement="SequenceFlow_1j4x1ej">
-        <di:waypoint x="739" y="120" />
-        <di:waypoint x="770" y="120" />
+        <di:waypoint xsi:type="dc:Point" x="894" y="120" />
+        <di:waypoint xsi:type="dc:Point" x="952" y="120" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="878" y="99" width="90" height="12" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0xndboi_di" bpmnElement="SequenceFlow_0xndboi">
+        <di:waypoint xsi:type="dc:Point" x="365" y="256" />
+        <di:waypoint xsi:type="dc:Point" x="452" y="256" />
+        <di:waypoint xsi:type="dc:Point" x="452" y="256" />
+        <di:waypoint xsi:type="dc:Point" x="539" y="256" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="560" y="99" width="0" height="12" />
+          <dc:Bounds x="422" y="249.5" width="90" height="13" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
-      <bpmndi:BPMNShape id="ServiceTask_0tg4hn9_di" bpmnElement="SetTimerDuration">
-        <dc:Bounds x="274" y="80" width="100" height="80" />
+      <bpmndi:BPMNShape id="ServiceTask_0krf1ur_di" bpmnElement="Setup_AAI_Inventory_Audit">
+        <dc:Bounds x="265" y="216" width="100" height="80" />
       </bpmndi:BPMNShape>
-      <bpmndi:BPMNShape id="IntermediateCatchEvent_17kjdjp_di" bpmnElement="Timer">
-        <dc:Bounds x="417" y="102" width="36" height="36" />
+      <bpmndi:BPMNShape id="ServiceTask_08rxjeb_di" bpmnElement="Audit_AAI_Inventory">
+        <dc:Bounds x="539" y="216" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="BoundaryEvent_0s7rszu_di" bpmnElement="BoundaryEvent_1nb1hw4">
+        <dc:Bounds x="575" y="278" width="36" height="36" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="421" y="145" width="29" height="14" />
+          <dc:Bounds x="548" y="317" width="90" height="13" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNShape>
-      <bpmndi:BPMNEdge id="SequenceFlow_0qc2sao_di" bpmnElement="SequenceFlow_0qc2sao">
-        <di:waypoint x="374" y="120" />
-        <di:waypoint x="417" y="120" />
+      <bpmndi:BPMNEdge id="SequenceFlow_1t99ceh_di" bpmnElement="SequenceFlow_1t99ceh">
+        <di:waypoint xsi:type="dc:Point" x="593" y="314" />
+        <di:waypoint xsi:type="dc:Point" x="593" y="348" />
+        <di:waypoint xsi:type="dc:Point" x="593" y="348" />
+        <di:waypoint xsi:type="dc:Point" x="593" y="371" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="563" y="341.5" width="90" height="13" />
+        </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge id="SequenceFlow_0e44ywc_di" bpmnElement="SequenceFlow_0e44ywc">
-        <di:waypoint x="453" y="120" />
-        <di:waypoint x="490" y="120" />
+      <bpmndi:BPMNShape id="ServiceTask_0eujimg_di" bpmnElement="Task_0swpw3v">
+        <dc:Bounds x="543" y="371" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ExclusiveGateway_1v8bmbu_di" bpmnElement="ExclusiveGateway_1v8bmbu" isMarkerVisible="true">
+        <dc:Bounds x="290" y="95" width="50" height="50" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="315" y="148" width="0" height="13" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_07ybdik_di" bpmnElement="SequenceFlow_07ybdik">
+        <di:waypoint xsi:type="dc:Point" x="340" y="120" />
+        <di:waypoint xsi:type="dc:Point" x="539" y="120" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="439.5" y="98.5" width="0" height="13" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0ghzwlo_di" bpmnElement="SequenceFlow_0ghzwlo">
+        <di:waypoint xsi:type="dc:Point" x="315" y="145" />
+        <di:waypoint xsi:type="dc:Point" x="315" y="216" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="330" y="174" width="0" height="13" />
+        </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge id="SequenceFlow_1yzril6_di" bpmnElement="SequenceFlow_1yzril6">
-        <di:waypoint x="590" y="120" />
-        <di:waypoint x="639" y="120" />
+      <bpmndi:BPMNEdge id="SequenceFlow_0ee42yq_di" bpmnElement="SequenceFlow_0ee42yq">
+        <di:waypoint xsi:type="dc:Point" x="589" y="216" />
+        <di:waypoint xsi:type="dc:Point" x="589" y="193" />
+        <di:waypoint xsi:type="dc:Point" x="589" y="193" />
+        <di:waypoint xsi:type="dc:Point" x="589" y="160" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="604" y="186.5" width="0" height="13" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="ServiceTask_1eg5ryx_di" bpmnElement="CheckAuditVariable">
+        <dc:Bounds x="161" y="80" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_1xqyur9_di" bpmnElement="SequenceFlow_1xqyur9">
+        <di:waypoint xsi:type="dc:Point" x="261" y="120" />
+        <di:waypoint xsi:type="dc:Point" x="290" y="120" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="275.5" y="98.5" width="0" height="13" />
+        </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
     </bpmndi:BPMNPlane>
   </bpmndi:BPMNDiagram>
index bd126de..08252f6 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.10.0">
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.7.1">
   <bpmn:process id="CreateVfModuleBB" name="CreateVfModuleBB" isExecutable="true">
     <bpmn:startEvent id="CreateVfModuleBB_Start">
       <bpmn:outgoing>SequenceFlow_1xr6chl</bpmn:outgoing>
@@ -10,7 +10,7 @@
     </bpmn:serviceTask>
     <bpmn:sequenceFlow id="SequenceFlow_1xr6chl" sourceRef="CreateVfModuleBB_Start" targetRef="QueryVnf" />
     <bpmn:endEvent id="CreateVfModuleBB_End">
-      <bpmn:incoming>SequenceFlow_1stomxq</bpmn:incoming>
+      <bpmn:incoming>SequenceFlow_1vbwdaw</bpmn:incoming>
     </bpmn:endEvent>
     <bpmn:serviceTask id="CreateVfModule" name="Create VF Module (VNF)" camunda:expression="${VnfAdapterCreateTasks.createVfModule(InjectExecution.execute(execution, execution.getVariable(&#34;gBuildingBlockExecution&#34;)))}">
       <bpmn:incoming>SequenceFlow_15hn8si</bpmn:incoming>
       <bpmn:incoming>SequenceFlow_16g4dz0</bpmn:incoming>
       <bpmn:outgoing>SequenceFlow_0ecr393</bpmn:outgoing>
     </bpmn:callActivity>
-    <bpmn:sequenceFlow id="SequenceFlow_1stomxq" sourceRef="UpdateVfModuleStatus" targetRef="CreateVfModuleBB_End" />
     <bpmn:serviceTask id="UpdateVfModuleStatus" name="&#10;AAI&#10;Update&#10;(vf module)&#10;" camunda:expression="${AAIUpdateTasks.updateOrchestrationStatusCreatedVfModule(InjectExecution.execute(execution, execution.getVariable(&#34;gBuildingBlockExecution&#34;)))}">
-      <bpmn:incoming>SequenceFlow_0qqsilv</bpmn:incoming>
-      <bpmn:outgoing>SequenceFlow_1stomxq</bpmn:outgoing>
+      <bpmn:incoming>SequenceFlow_0rds4rj</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_1vbwdaw</bpmn:outgoing>
     </bpmn:serviceTask>
-    <bpmn:sequenceFlow id="SequenceFlow_0qqsilv" sourceRef="UpdateVfModuleHeatStackId" targetRef="UpdateVfModuleStatus" />
     <bpmn:serviceTask id="UpdateVfModuleHeatStackId" name="&#10;AAI&#10;Update&#10;(vf module)&#10;" camunda:expression="${AAIUpdateTasks.updateHeatStackIdVfModule(InjectExecution.execute(execution, execution.getVariable(&#34;gBuildingBlockExecution&#34;)))}">
       <bpmn:incoming>SequenceFlow_0ecr393</bpmn:incoming>
-      <bpmn:outgoing>SequenceFlow_0qqsilv</bpmn:outgoing>
+      <bpmn:outgoing>SequenceFlow_0rds4rj</bpmn:outgoing>
     </bpmn:serviceTask>
     <bpmn:subProcess id="SubProcess_1getwnf" name="Error Handling&#10;&#10;" triggeredByEvent="true">
       <bpmn:startEvent id="StartEvent_1c8o652">
@@ -55,6 +53,8 @@
       </bpmn:endEvent>
       <bpmn:sequenceFlow id="SequenceFlow_0gcots6" sourceRef="StartEvent_1c8o652" targetRef="EndEvent_1emam1w" />
     </bpmn:subProcess>
+    <bpmn:sequenceFlow id="SequenceFlow_0rds4rj" sourceRef="UpdateVfModuleHeatStackId" targetRef="UpdateVfModuleStatus" />
+    <bpmn:sequenceFlow id="SequenceFlow_1vbwdaw" sourceRef="UpdateVfModuleStatus" targetRef="CreateVfModuleBB_End" />
   </bpmn:process>
   <bpmndi:BPMNDiagram id="BPMNDiagram_1">
     <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="CreateVfModuleBB">
@@ -75,9 +75,9 @@
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNShape id="EndEvent_0qdq7wj_di" bpmnElement="CreateVfModuleBB_End">
-        <dc:Bounds x="1278" y="88" width="36" height="36" />
+        <dc:Bounds x="1299" y="88" width="36" height="36" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="1286" y="128" width="19" height="12" />
+          <dc:Bounds x="1272" y="128" width="90" height="12" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape id="ServiceTask_1dgenhy_di" bpmnElement="CreateVfModule">
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNEdge id="SequenceFlow_0ecr393_di" bpmnElement="SequenceFlow_0ecr393">
-        <di:waypoint xsi:type="dc:Point" x="877" y="106" />
-        <di:waypoint xsi:type="dc:Point" x="950" y="106" />
+        <di:waypoint xsi:type="dc:Point" x="877" y="107" />
+        <di:waypoint xsi:type="dc:Point" x="931" y="107" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="869" y="91" width="90" height="0" />
+          <dc:Bounds x="859" y="92" width="90" height="0" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNShape id="CallActivity_1i1pfzb_di" bpmnElement="VnfAdapter">
         <dc:Bounds x="777" y="66" width="100" height="80" />
       </bpmndi:BPMNShape>
-      <bpmndi:BPMNEdge id="SequenceFlow_1stomxq_di" bpmnElement="SequenceFlow_1stomxq">
-        <di:waypoint xsi:type="dc:Point" x="1214" y="106" />
-        <di:waypoint xsi:type="dc:Point" x="1278" y="106" />
-        <bpmndi:BPMNLabel>
-          <dc:Bounds x="1201" y="91" width="90" height="0" />
-        </bpmndi:BPMNLabel>
-      </bpmndi:BPMNEdge>
       <bpmndi:BPMNShape id="ServiceTask_0fpfn71_di" bpmnElement="UpdateVfModuleStatus">
-        <dc:Bounds x="1114" y="66" width="100" height="80" />
+        <dc:Bounds x="1117" y="66" width="100" height="80" />
       </bpmndi:BPMNShape>
-      <bpmndi:BPMNEdge id="SequenceFlow_0qqsilv_di" bpmnElement="SequenceFlow_0qqsilv">
-        <di:waypoint xsi:type="dc:Point" x="1050" y="106" />
-        <di:waypoint xsi:type="dc:Point" x="1114" y="106" />
-        <bpmndi:BPMNLabel>
-          <dc:Bounds x="1037" y="91" width="90" height="0" />
-        </bpmndi:BPMNLabel>
-      </bpmndi:BPMNEdge>
       <bpmndi:BPMNShape id="ServiceTask_04k1b85_di" bpmnElement="UpdateVfModuleHeatStackId">
-        <dc:Bounds x="950" y="66" width="100" height="80" />
+        <dc:Bounds x="931" y="68" width="100" height="80" />
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape id="SubProcess_1getwnf_di" bpmnElement="SubProcess_1getwnf" isExpanded="true">
         <dc:Bounds x="172" y="276" width="231" height="135" />
           <dc:Bounds x="297.5" y="331" width="0" height="12" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0rds4rj_di" bpmnElement="SequenceFlow_0rds4rj">
+        <di:waypoint xsi:type="dc:Point" x="1031" y="107" />
+        <di:waypoint xsi:type="dc:Point" x="1117" y="107" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1074" y="85" width="0" height="13" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1vbwdaw_di" bpmnElement="SequenceFlow_1vbwdaw">
+        <di:waypoint xsi:type="dc:Point" x="1217" y="106" />
+        <di:waypoint xsi:type="dc:Point" x="1299" y="106" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1258" y="84" width="0" height="13" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
     </bpmndi:BPMNPlane>
   </bpmndi:BPMNDiagram>
 </bpmn:definitions>
index 9be4cd0..943ce12 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.10.0">
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.7.1">
   <bpmn:process id="ExecuteBuildingBlock" name="ExecuteBuildingBlock" isExecutable="true">
     <bpmn:startEvent id="Start_ExecuteBuildingBlock" name="start">
       <bpmn:outgoing>SequenceFlow_0rq4c5r</bpmn:outgoing>
@@ -37,7 +37,7 @@
     <bpmn:subProcess id="SubProcess_0tv8zda" name="Error Handling&#10;&#10;" triggeredByEvent="true">
       <bpmn:startEvent id="StartEvent_0tmcs9g">
         <bpmn:outgoing>SequenceFlow_09synl9</bpmn:outgoing>
-        <bpmn:errorEventDefinition />
+        <bpmn:errorEventDefinition camunda:errorCodeVariable="WorkflowExceptionCode" camunda:errorMessageVariable="WorkflowExceptionMessage" />
       </bpmn:startEvent>
       <bpmn:sequenceFlow id="SequenceFlow_09synl9" sourceRef="StartEvent_0tmcs9g" targetRef="Task_QueryRainyDayTable" />
       <bpmn:serviceTask id="Task_QueryRainyDayTable" name="QueryRainyDayTable" camunda:expression="${ExecuteBuildingBlockRainyDay.queryRainyDayTable(execution,true)}">
   </bpmn:process>
   <bpmn:error id="Error_0tnktdw" name="Error" errorCode="java.lang.Exception" />
   <bpmn:error id="Error_17zcdbk" name="Bpmn Error" />
+  <bpmn:error id="Error_123q3fr" name="Error_1h13m8l" />
+  <bpmn:error id="Error_1ivyybb" name="Error_1e4p3cf" />
+  <bpmn:error id="Error_1c60d7i" name="Error_0qrs661" />
+  <bpmn:error id="Error_1owi18u" name="Error_2eiqdl7" />
+  <bpmn:error id="Error_0snha16" />
   <bpmndi:BPMNDiagram id="BPMNDiagram_1">
     <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="ExecuteBuildingBlock">
       <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="Start_ExecuteBuildingBlock">
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNShape id="ExclusiveGateway_0ey4zpt_di" bpmnElement="ExclusiveGateway_0ey4zpt" isMarkerVisible="true">
-        <dc:Bounds x="724" y="367" width="50" height="50" />
+        <dc:Bounds x="721" y="385" width="50" height="50" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="719" y="342" width="62" height="12" />
+          <dc:Bounds x="716" y="360" width="63" height="13" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape id="IntermediateCatchEvent_0qjyidb_di" bpmnElement="IntermediateCatchEvent_RetryTimer">
-        <dc:Bounds x="968" y="374" width="36" height="36" />
+        <dc:Bounds x="965" y="392" width="36" height="36" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="959" y="349" width="55" height="12" />
+          <dc:Bounds x="956" y="367" width="55" height="13" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape id="ExclusiveGateway_1aonzik_di" bpmnElement="ExclusiveGateway_1aonzik" isMarkerVisible="true">
-        <dc:Bounds x="571" y="367" width="50" height="50" />
+        <dc:Bounds x="568" y="385" width="50" height="50" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="562" y="329" width="68" height="24" />
+          <dc:Bounds x="558" y="347" width="70" height="25" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNEdge id="SequenceFlow_1wbevp0_di" bpmnElement="SequenceFlow_1wbevp0">
-        <di:waypoint xsi:type="dc:Point" x="774" y="392" />
-        <di:waypoint xsi:type="dc:Point" x="839" y="392" />
+        <di:waypoint xsi:type="dc:Point" x="771" y="410" />
+        <di:waypoint xsi:type="dc:Point" x="836" y="410" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="790.2777777777778" y="367" width="18" height="12" />
+          <dc:Bounds x="788" y="385" width="18" height="13" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNEdge id="SequenceFlow_0fwsjva_di" bpmnElement="SequenceFlow_0fwsjva">
-        <di:waypoint xsi:type="dc:Point" x="621" y="392" />
-        <di:waypoint xsi:type="dc:Point" x="724" y="392" />
+        <di:waypoint xsi:type="dc:Point" x="618" y="410" />
+        <di:waypoint xsi:type="dc:Point" x="721" y="410" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="659" y="400" width="27" height="12" />
+          <dc:Bounds x="656" y="418" width="27" height="13" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNEdge id="SequenceFlow_0h8v45y_di" bpmnElement="SequenceFlow_0h8v45y">
-        <di:waypoint xsi:type="dc:Point" x="596" y="417" />
-        <di:waypoint xsi:type="dc:Point" x="596" y="473" />
+        <di:waypoint xsi:type="dc:Point" x="593" y="435" />
+        <di:waypoint xsi:type="dc:Point" x="593" y="491" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="603" y="438" width="84" height="12" />
+          <dc:Bounds x="600" y="456" width="85" height="13" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNShape id="ServiceTask_1tifgqh_di" bpmnElement="Task_QueryRainyDayTable">
-        <dc:Bounds x="428" y="352" width="100" height="80" />
+        <dc:Bounds x="425" y="370" width="100" height="80" />
       </bpmndi:BPMNShape>
       <bpmndi:BPMNEdge id="SequenceFlow_0ndt8ft_di" bpmnElement="SequenceFlow_0ndt8ft">
-        <di:waypoint xsi:type="dc:Point" x="939" y="392" />
-        <di:waypoint xsi:type="dc:Point" x="968" y="392" />
+        <di:waypoint xsi:type="dc:Point" x="936" y="410" />
+        <di:waypoint xsi:type="dc:Point" x="965" y="410" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="908.5" y="371" width="90" height="12" />
+          <dc:Bounds x="906" y="389" width="90" height="12" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNEdge id="SequenceFlow_07a1ytc_di" bpmnElement="SequenceFlow_07a1ytc">
-        <di:waypoint xsi:type="dc:Point" x="1004" y="392" />
-        <di:waypoint xsi:type="dc:Point" x="1042" y="392" />
+        <di:waypoint xsi:type="dc:Point" x="1001" y="410" />
+        <di:waypoint xsi:type="dc:Point" x="1039" y="410" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="978" y="371" width="90" height="12" />
+          <dc:Bounds x="975" y="389" width="90" height="12" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNShape id="ServiceTask_1obvxht_di" bpmnElement="Task_SetRetryTimer">
-        <dc:Bounds x="839" y="352" width="100" height="80" />
+        <dc:Bounds x="836" y="370" width="100" height="80" />
       </bpmndi:BPMNShape>
       <bpmndi:BPMNEdge id="SequenceFlow_0kdjsnx_di" bpmnElement="Continue">
         <di:waypoint xsi:type="dc:Point" x="508" y="180" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNEdge id="SequenceFlow_0a62t4c_di" bpmnElement="SequenceFlow_0a62t4c">
-        <di:waypoint xsi:type="dc:Point" x="528" y="392" />
-        <di:waypoint xsi:type="dc:Point" x="571" y="392" />
+        <di:waypoint xsi:type="dc:Point" x="525" y="410" />
+        <di:waypoint xsi:type="dc:Point" x="568" y="410" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="505" y="371" width="90" height="13" />
+          <dc:Bounds x="502" y="389" width="90" height="13" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNShape id="SubProcess_0tv8zda_di" bpmnElement="SubProcess_0tv8zda" isExpanded="true">
-        <dc:Bounds x="323" y="276" width="802" height="290" />
+        <dc:Bounds x="320" y="294" width="802" height="290" />
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape id="StartEvent_0tmcs9g_di" bpmnElement="StartEvent_0tmcs9g">
-        <dc:Bounds x="343" y="374" width="36" height="36" />
+        <dc:Bounds x="340" y="392" width="36" height="36" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="226" y="410" width="90" height="12" />
+          <dc:Bounds x="223" y="428" width="90" height="12" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNEdge id="SequenceFlow_09synl9_di" bpmnElement="SequenceFlow_09synl9">
-        <di:waypoint xsi:type="dc:Point" x="379" y="392" />
-        <di:waypoint xsi:type="dc:Point" x="428" y="392" />
+        <di:waypoint xsi:type="dc:Point" x="376" y="410" />
+        <di:waypoint xsi:type="dc:Point" x="425" y="410" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="359" y="371" width="90" height="12" />
+          <dc:Bounds x="356" y="389" width="90" height="12" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNShape id="EndEvent_0mvmk3i_di" bpmnElement="EndEvent_0mvmk3i">
-        <dc:Bounds x="578" y="473" width="36" height="36" />
+        <dc:Bounds x="575" y="491" width="36" height="36" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="551" y="513" width="90" height="12" />
+          <dc:Bounds x="548" y="531" width="90" height="12" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape id="EndEvent_1aww7yx_di" bpmnElement="EndEvent_1sez2lh">
-        <dc:Bounds x="1042" y="374" width="36" height="36" />
+        <dc:Bounds x="1039" y="392" width="36" height="36" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="1052" y="414" width="18" height="12" />
+          <dc:Bounds x="1049" y="432" width="19" height="13" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNEdge id="SequenceFlow_16lmcxp_di" bpmnElement="SequenceFlow_16lmcxp">
         <dc:Bounds x="906" y="140" width="100" height="80" />
       </bpmndi:BPMNShape>
       <bpmndi:BPMNEdge id="SequenceFlow_0541bid_di" bpmnElement="SequenceFlow_0541bid">
-        <di:waypoint xsi:type="dc:Point" x="749" y="417" />
-        <di:waypoint xsi:type="dc:Point" x="749" y="441" />
+        <di:waypoint xsi:type="dc:Point" x="746" y="435" />
+        <di:waypoint xsi:type="dc:Point" x="746" y="459" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="760" y="418" width="12" height="12" />
+          <dc:Bounds x="757" y="436" width="13" height="13" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNEdge id="SequenceFlow_12ps9at_di" bpmnElement="SequenceFlow_12ps9at">
-        <di:waypoint xsi:type="dc:Point" x="799" y="481" />
-        <di:waypoint xsi:type="dc:Point" x="871" y="481" />
+        <di:waypoint xsi:type="dc:Point" x="796" y="499" />
+        <di:waypoint xsi:type="dc:Point" x="868" y="499" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="835" y="460" width="0" height="12" />
+          <dc:Bounds x="787" y="478" width="90" height="12" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNShape id="EndEvent_05vw85n_di" bpmnElement="EndEvent_0ex9298">
-        <dc:Bounds x="871" y="463" width="36" height="36" />
+        <dc:Bounds x="868" y="481" width="36" height="36" />
         <bpmndi:BPMNLabel>
-          <dc:Bounds x="880" y="503" width="18" height="12" />
+          <dc:Bounds x="877" y="521" width="19" height="13" />
         </bpmndi:BPMNLabel>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape id="ServiceTask_11f2c91_di" bpmnElement="Task_QuerySecondaryPolicy">
-        <dc:Bounds x="699" y="441" width="100" height="80" />
+        <dc:Bounds x="696" y="459" width="100" height="80" />
       </bpmndi:BPMNShape>
     </bpmndi:BPMNPlane>
   </bpmndi:BPMNDiagram>
index f501151..79bade3 100644 (file)
@@ -23,7 +23,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-
+import org.camunda.bpm.engine.ExternalTaskService;
 import org.camunda.bpm.engine.RepositoryService;
 import org.camunda.bpm.engine.RuntimeService;
 import org.camunda.bpm.extension.mockito.mock.FluentJavaDelegateMock;
@@ -50,6 +50,7 @@ import org.onap.so.bpmn.infrastructure.adapter.vnf.tasks.VnfAdapterCreateTasks;
 import org.onap.so.bpmn.infrastructure.adapter.vnf.tasks.VnfAdapterDeleteTasks;
 import org.onap.so.bpmn.infrastructure.adapter.vnf.tasks.VnfAdapterImpl;
 import org.onap.so.bpmn.infrastructure.appc.tasks.AppcRunTasks;
+import org.onap.so.bpmn.infrastructure.audit.AuditTasks;
 import org.onap.so.bpmn.infrastructure.flowspecific.tasks.ActivateVfModule;
 import org.onap.so.bpmn.infrastructure.flowspecific.tasks.AssignNetwork;
 import org.onap.so.bpmn.infrastructure.flowspecific.tasks.AssignNetworkBBUtils;
@@ -93,6 +94,9 @@ public abstract class BaseBPMNTest {
        @Autowired
        protected RuntimeService runtimeService;
 
+       @Autowired
+       protected ExternalTaskService externalTaskService;
+       
        @Autowired
        private RepositoryService repositoryService;
 
@@ -227,6 +231,9 @@ public abstract class BaseBPMNTest {
        
        @MockBean
        protected WorkflowActionBBFailure workflowActionBBFailure;
+       
+       @MockBean
+       protected AuditTasks auditTasks;
 
        @LocalServerPort
        protected int port;
index 1bce605..9ffcd9d 100644 (file)
 package org.onap.so.bpmn.infrastructure.bpmn.subprocess;
 import static org.camunda.bpm.engine.test.assertions.bpmn.BpmnAwareAssertions.assertThat;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import java.io.IOException;
+import java.util.List;
+
 import org.camunda.bpm.engine.delegate.BpmnError;
+import org.camunda.bpm.engine.externaltask.LockedExternalTask;
 import org.camunda.bpm.engine.runtime.ProcessInstance;
 import org.junit.Before;
 import org.junit.Test;
@@ -35,17 +39,25 @@ public class ActivateVfModuleBBTest extends BaseBPMNTest{
        @Before
        public void before() {
                variables.put("vfModuleActivateTimerDuration", "PT2S");
+               variables.put("auditInventoryNeeded", "true");
        }
 
        @Test
        public void sunnyDay() throws InterruptedException, IOException {
                mockSubprocess("SDNCHandler", "My Mock Process Name", "GenericStub");
                ProcessInstance pi = runtimeService.startProcessInstanceByKey("ActivateVfModuleBB", variables);
-               while(runtimeService.createProcessInstanceQuery().processInstanceId(pi.getId()).singleResult() != null) {
-                       Thread.sleep(1000);
-               }
+               List<LockedExternalTask> tasks = externalTaskService.fetchAndLock(100, "externalWorkerId")
+                .topic("InventoryAudit", 60L * 1000L).execute();
+        while (!tasks.isEmpty()) {
+            for (LockedExternalTask task : tasks) {
+                externalTaskService.complete(task.getId(), "externalWorkerId");
+            }
+            tasks = externalTaskService.fetchAndLock(100, "externalWorkerId")
+                    .topic("InventoryAudit", 60L * 1000L).execute();
+        }
+               
                assertThat(pi).isNotNull();
-               assertThat(pi).isStarted().hasPassedInOrder("ActivateVfModuleBB_Start", "SetTimerDuration", "Timer", "ActivateVfModule", "CallActivity_sdncHandler",
+               assertThat(pi).isStarted().hasPassedInOrder("ActivateVfModuleBB_Start","ExclusiveGateway_1v8bmbu","Setup_AAI_Inventory_Audit", "Audit_AAI_Inventory", "ActivateVfModule", "CallActivity_sdncHandler",
                                "UpdateVfModuleActiveStatus", "ActivateVfModuleBB_End");
                assertThat(pi).isEnded();
        }
@@ -55,11 +67,18 @@ public class ActivateVfModuleBBTest extends BaseBPMNTest{
                mockSubprocess("SDNCHandler", "My Mock Process Name", "GenericStub");
                doThrow(BpmnError.class).when(aaiUpdateTasks).updateOrchestrationStatusActivateVfModule(any(BuildingBlockExecution.class));
                ProcessInstance pi = runtimeService.startProcessInstanceByKey("ActivateVfModuleBB", variables);
-               while(runtimeService.createProcessInstanceQuery().processInstanceId(pi.getId()).singleResult() != null) {
-                       Thread.sleep(1000);
-               }
+               List<LockedExternalTask> tasks = externalTaskService.fetchAndLock(100, "externalWorkerId")
+                .topic("InventoryAudit", 60L * 1000L).execute();
+        while (!tasks.isEmpty()) {
+            for (LockedExternalTask task : tasks) {
+                externalTaskService.complete(task.getId(), "externalWorkerId");
+            }
+            tasks = externalTaskService.fetchAndLock(100, "externalWorkerId")
+                    .topic("InventoryAudit", 60L * 1000L).execute();
+        }
+
                assertThat(pi).isNotNull().isStarted()
-                               .hasPassedInOrder("ActivateVfModuleBB_Start", "SetTimerDuration", "Timer", "ActivateVfModule", "UpdateVfModuleActiveStatus")
+                               .hasPassedInOrder("ActivateVfModuleBB_Start","ExclusiveGateway_1v8bmbu","Setup_AAI_Inventory_Audit", "Audit_AAI_Inventory", "ActivateVfModule", "UpdateVfModuleActiveStatus")
                                .hasNotPassed("ActivateVfModuleBB_End");
        }
 }
index 1090ab7..c36172c 100644 (file)
@@ -31,6 +31,10 @@ log:
     vnfAdapterCreateV1: 'true'
     vnfAdapterRestV1: 'true'
 mso:
+  infra:
+    auditInventory: true
+    customer:
+      id: testCustIdInfra
   adapters:
     completemsoprocess:
       endpoint: http://localhost:28090/CompleteMsoProcess
@@ -96,9 +100,6 @@ mso:
   healthcheck:
     log:
       debug: 'false'
-  infra:
-    customer:
-      id: testCustIdInfra
   logPath: logs
   msoKey: 07a7159d3bf51a0e53be7a8f89699be7
   po:
index 64b6bfc..d8f6ba3 100644 (file)
@@ -26,5 +26,5 @@
   </root>
 
   <logger name="wiremock.org" level="DEBUG" />
-<logger name="org.camunda" level="DEBUG" />
+
 </configuration>
\ No newline at end of file
index becb66a..0243ce8 100644 (file)
                        <artifactId>so-bpmn-infrastructure-common</artifactId>
                        <version>${project.version}</version>
                </dependency>
+               <dependency>
+                       <groupId>org.onap.so.adapters</groupId>
+                       <artifactId>mso-adapter-utils</artifactId>
+                       <version>${project.version}</version>
+               </dependency>
                <dependency>
                        <groupId>org.onap.sdnc.northbound</groupId>
                        <artifactId>generic-resource-api-client</artifactId>
diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/audit/AuditTasks.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/audit/AuditTasks.java
new file mode 100644 (file)
index 0000000..aaa9e51
--- /dev/null
@@ -0,0 +1,83 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.bpmn.infrastructure.audit;
+
+
+import org.onap.so.audit.beans.AuditInventory;
+import org.onap.so.bpmn.common.BuildingBlockExecution;
+import org.onap.so.bpmn.servicedecomposition.bbobjects.CloudRegion;
+import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
+import org.onap.so.bpmn.servicedecomposition.entities.GeneralBuildingBlock;
+import org.onap.so.bpmn.servicedecomposition.entities.ResourceKey;
+import org.onap.so.bpmn.servicedecomposition.tasks.ExtractPojosForBB;
+import org.onap.so.client.exception.BBObjectNotFoundException;
+import org.onap.so.client.exception.ExceptionBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AuditTasks {
+       
+       private static final Logger logger = LoggerFactory.getLogger(AuditTasks.class);
+
+       @Autowired
+       private ExceptionBuilder exceptionUtil;
+       
+       @Autowired
+       private ExtractPojosForBB extractPojosForBB;
+       
+       @Autowired
+       private Environment env;
+       
+       public void isAuditNeeded(BuildingBlockExecution execution) {
+               try {                   
+                       logger.debug("auditInventoryNeeded Value: {}", env.getProperty("mso.infra.auditInventory"));
+                       execution.setVariable("auditInventoryNeeded",env.getProperty("mso.infra.auditInventory"));
+               } catch (Exception ex) {
+                       exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
+               }
+       }
+
+       public void setupAuditVariable(BuildingBlockExecution execution) {
+               try {
+                       execution.setVariable("auditInventory",createAuditInventory(execution));
+               } catch (Exception ex) {
+                       exceptionUtil.buildAndThrowWorkflowException(execution, 7000, ex);
+               }
+       }
+       
+       private AuditInventory createAuditInventory(BuildingBlockExecution execution) throws BBObjectNotFoundException {
+                       AuditInventory auditInventory = new AuditInventory();
+                       
+                       GeneralBuildingBlock gBBInput = execution.getGeneralBuildingBlock();
+                       VfModule vfModule = extractPojosForBB.extractByKey(execution, ResourceKey.VF_MODULE_ID, execution.getLookupMap().get(ResourceKey.VF_MODULE_ID));
+                       CloudRegion cloudRegion = gBBInput.getCloudRegion();
+                       
+                       auditInventory.setCloudOwner(cloudRegion.getCloudOwner());
+                       auditInventory.setCloudRegion(cloudRegion.getLcpCloudRegionId());
+                       auditInventory.setTenantId(cloudRegion.getTenantId());
+                       auditInventory.setHeatStackName(vfModule.getVfModuleName());
+                       return auditInventory;
+       }
+}
diff --git a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/audit/AuditTasksTest.java b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/audit/AuditTasksTest.java
new file mode 100644 (file)
index 0000000..7a9e2bb
--- /dev/null
@@ -0,0 +1,74 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.bpmn.infrastructure.audit;
+
+import static com.shazam.shazamcrest.MatcherAssert.assertThat;
+import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.ArgumentMatchers;
+import org.mockito.InjectMocks;
+import org.onap.so.audit.beans.AuditInventory;
+import org.onap.so.bpmn.BaseTaskTest;
+import org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf;
+import org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance;
+import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
+import org.onap.so.bpmn.servicedecomposition.entities.ResourceKey;
+import org.onap.so.client.exception.BBObjectNotFoundException;
+
+public class AuditTasksTest extends BaseTaskTest{
+       
+       @InjectMocks
+       private AuditTasks auditTasks = new AuditTasks();
+       private ServiceInstance serviceInstance;
+       private GenericVnf genericVnf;
+       private VfModule vfModule;
+
+       
+       @Rule
+       public final ExpectedException exception = ExpectedException.none();
+       
+       @Before
+       public void before() throws BBObjectNotFoundException {
+               serviceInstance = setServiceInstance();         
+               genericVnf = setGenericVnf();
+               vfModule = setVfModule();
+               setCloudRegion();
+               when(extractPojosForBB.extractByKey(any(),ArgumentMatchers.eq(ResourceKey.GENERIC_VNF_ID), any())).thenReturn(genericVnf);
+               when(extractPojosForBB.extractByKey(any(),ArgumentMatchers.eq(ResourceKey.VF_MODULE_ID), any())).thenReturn(vfModule);
+               when(extractPojosForBB.extractByKey(any(),ArgumentMatchers.eq(ResourceKey.SERVICE_INSTANCE_ID), any())).thenReturn(serviceInstance);
+       }
+       
+       @Test
+       public void setupAuditVariableTest() throws Exception {
+               AuditInventory expectedAuditInventory = new AuditInventory();
+               expectedAuditInventory.setCloudOwner("testCloudOwner");
+               expectedAuditInventory.setCloudRegion("testLcpCloudRegionId");
+               expectedAuditInventory.setHeatStackName("testVfModuleName1");
+               expectedAuditInventory.setTenantId("testTenantId");
+               auditTasks.setupAuditVariable(execution);
+               assertThat((AuditInventory)execution.getVariable("auditInventory"), sameBeanAs(expectedAuditInventory));
+       }
+}
index 12e0ebe..7eadea0 100644 (file)
@@ -49,6 +49,8 @@ public class AAIObjectPlurals implements GraphInventoryObjectPlurals, Serializab
        public static final AAIObjectPlurals DEFAULT_TENANT = new AAIObjectPlurals(AAINamespaceConstants.CLOUD_INFRASTRUCTURE + "/cloud-regions/cloud-region/" + Defaults.CLOUD_OWNER + "/AAIAIC25", "/tenants", "default-tenant");
        public static final AAIObjectPlurals NETWORK_TECHNOLOGY = new AAIObjectPlurals(AAINamespaceConstants.CLOUD_INFRASTRUCTURE, "/network-technologies", "network-technology");
        public static final AAIObjectPlurals LOGICAL_LINK = new AAIObjectPlurals(AAINamespaceConstants.NETWORK, "/logical-links", "logical-link");
+       public static final AAIObjectPlurals L_INTERFACE = new AAIObjectPlurals(AAIObjectType.VSERVER.uriTemplate(), "/l-interfaces", "l-interface");
+       public static final AAIObjectPlurals SUB_L_INTERFACE = new AAIObjectPlurals(AAIObjectType.L_INTERFACE.uriTemplate(), "/l-interfaces", "l-interface");
 
        private final String uriTemplate;
        private final String partialUri;
index a6a9acf..66ff59d 100644 (file)
@@ -43,6 +43,7 @@ import org.onap.aai.domain.yang.ExtAaiNetwork;
 import org.onap.aai.domain.yang.GenericVnf;
 import org.onap.aai.domain.yang.InstanceGroup;
 import org.onap.aai.domain.yang.L3Network;
+import org.onap.aai.domain.yang.LInterface;
 import org.onap.aai.domain.yang.LineOfBusiness;
 import org.onap.aai.domain.yang.ModelVer;
 import org.onap.aai.domain.yang.NetworkPolicy;
@@ -131,6 +132,7 @@ public class AAIObjectType implements GraphInventoryObjectType, Serializable {
        public static final AAIObjectType DEVICE = new AAIObjectType(AAINamespaceConstants.NETWORK, Device.class);
        public static final AAIObjectType EXT_AAI_NETWORK = new AAIObjectType(AAINamespaceConstants.NETWORK, ExtAaiNetwork.class);
        public static final AAIObjectType AGGREGATE_ROUTE = new AAIObjectType(AAINamespaceConstants.NETWORK, AggregateRoute.class);
+       public static final AAIObjectType L_INTERFACE = new AAIObjectType(AAIObjectType.VSERVER.uriTemplate(), LInterface.class);
        public static final AAIObjectType UNKNOWN = new AAIObjectType("", "", "unknown");
 
        private final String uriTemplate;