diff options
46 files changed, 2863 insertions, 395 deletions
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 index 0000000000..025d40d7c4 --- /dev/null +++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/audit/beans/AuditInventory.java @@ -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; + } + + + +} diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java index f132f10ebb..14aee2f4f2 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java +++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java @@ -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 { diff --git a/adapters/mso-openstack-adapters/pom.xml b/adapters/mso-openstack-adapters/pom.xml index 743c50dc75..8d4f30b631 100644 --- a/adapters/mso-openstack-adapters/pom.xml +++ b/adapters/mso-openstack-adapters/pom.xml @@ -269,5 +269,15 @@ <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> 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 index 0000000000..292cebf292 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AbstractAudit.java @@ -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 index 0000000000..38b00688a7 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackService.java @@ -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 index 0000000000..b0369395ed --- /dev/null +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackServiceData.java @@ -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 index 0000000000..6e6ecd51d4 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditVServer.java @@ -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 index 0000000000..7bba136da2 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/HeatStackAudit.java @@ -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 index 0000000000..c529413891 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/AaiClientPropertiesImpl.java @@ -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; + } +} diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/MsoOpenstackAdaptersApplication.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/MsoOpenstackAdaptersApplication.java index a9aa50f654..9408f0d681 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/MsoOpenstackAdaptersApplication.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/MsoOpenstackAdaptersApplication.java @@ -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 index 0000000000..4ce4d750a5 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/main/resources/META-INF/services/org.onap.so.client.RestProperties @@ -0,0 +1 @@ +org.onap.so.adapters.openstack.AaiClientPropertiesImpl
\ No newline at end of file diff --git a/adapters/mso-openstack-adapters/src/main/resources/application.yaml b/adapters/mso-openstack-adapters/src/main/resources/application.yaml index 8fd6d4279d..18084ced8d 100644 --- a/adapters/mso-openstack-adapters/src/main/resources/application.yaml +++ b/adapters/mso-openstack-adapters/src/main/resources/application.yaml @@ -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 index 0000000000..52b67b8eb9 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/AuditStackServiceDataTest.java @@ -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 index 0000000000..11e54404f4 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/AuditVServerTest.java @@ -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 index 0000000000..5df5d8200f --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/HeatStackAuditTest.java @@ -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 index 0000000000..27f971b698 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/resources/AVPNResourceGroupResponse.json @@ -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 index 0000000000..e0a2404eaf --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface0.json @@ -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 index 0000000000..e0631db0b5 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface0Resources.json @@ -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 index 0000000000..009533b476 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface1.json @@ -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 index 0000000000..1b10f16d6d --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface1Resources.json @@ -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 index 0000000000..7488ee2045 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface2.json @@ -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 index 0000000000..94c7c69de4 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface2Resources.json @@ -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 index 0000000000..33e282caa7 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/resources/GetResources.json @@ -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 index 0000000000..2350138076 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/resources/MISResourceGroupResponse.json @@ -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 index 0000000000..d879b3be59 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/resources/MISSubInterface0.json @@ -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 index 0000000000..5fa2795462 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/resources/MISSubInterface1Resources.json @@ -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 diff --git a/adapters/mso-openstack-adapters/src/test/resources/logback-test.xml b/adapters/mso-openstack-adapters/src/test/resources/logback-test.xml index 0611e62f3d..5d6eee746f 100644 --- a/adapters/mso-openstack-adapters/src/test/resources/logback-test.xml +++ b/adapters/mso-openstack-adapters/src/test/resources/logback-test.xml @@ -41,7 +41,11 @@ <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> diff --git a/asdc-controller/src/main/java/org/onap/so/asdc/installer/heat/ToscaResourceInstaller.java b/asdc-controller/src/main/java/org/onap/so/asdc/installer/heat/ToscaResourceInstaller.java index fe41aae4cd..ebc705ce30 100644 --- a/asdc-controller/src/main/java/org/onap/so/asdc/installer/heat/ToscaResourceInstaller.java +++ b/asdc-controller/src/main/java/org/onap/so/asdc/installer/heat/ToscaResourceInstaller.java @@ -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; } diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/ExecuteBuildingBlockRainyDay.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/ExecuteBuildingBlockRainyDay.java index d2e0b07dd1..b210b5ed2f 100644 --- a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/ExecuteBuildingBlockRainyDay.java +++ b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/ExecuteBuildingBlockRainyDay.java @@ -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"); } } diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/exception/ExceptionBuilder.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/exception/ExceptionBuilder.java index adffee6d42..459ef66e5b 100644 --- a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/exception/ExceptionBuilder.java +++ b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/exception/ExceptionBuilder.java @@ -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"); diff --git a/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/bpmn/servicedecomposition/tasks/ExecuteBuildlingBlockRainyDayTest.java b/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/bpmn/servicedecomposition/tasks/ExecuteBuildlingBlockRainyDayTest.java index cb5683dcc8..868aabf6a9 100644 --- a/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/bpmn/servicedecomposition/tasks/ExecuteBuildlingBlockRainyDayTest.java +++ b/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/bpmn/servicedecomposition/tasks/ExecuteBuildlingBlockRainyDayTest.java @@ -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"); diff --git a/bpmn/mso-infrastructure-bpmn/src/main/resources/application.yaml b/bpmn/mso-infrastructure-bpmn/src/main/resources/application.yaml index 203988a1a3..829fc12474 100644 --- a/bpmn/mso-infrastructure-bpmn/src/main/resources/application.yaml +++ b/bpmn/mso-infrastructure-bpmn/src/main/resources/application.yaml @@ -2,7 +2,9 @@ server: port: 8080 tomcat: max-threads: 50 - +mso: + infra: + auditInventory: true spring: datasource: driver-class-name: org.mariadb.jdbc.Driver diff --git a/bpmn/so-bpmn-building-blocks/pom.xml b/bpmn/so-bpmn-building-blocks/pom.xml index 4fe02ee3ac..0971a9d54e 100644 --- a/bpmn/so-bpmn-building-blocks/pom.xml +++ b/bpmn/so-bpmn-building-blocks/pom.xml @@ -147,6 +147,7 @@ <artifactId>mariaDB4j</artifactId> <version>2.2.3</version> <scope>test</scope> - </dependency> + </dependency> + </dependencies> </project> diff --git a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ActivateVfModuleBB.bpmn b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ActivateVfModuleBB.bpmn index 3670676a84..fd24be100b 100644 --- a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ActivateVfModuleBB.bpmn +++ b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ActivateVfModuleBB.bpmn @@ -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=" SDNC Activate (vf module) " camunda:expression="${SDNCActivateTasks.activateVfModule(InjectExecution.execute(execution, execution.getVariable("gBuildingBlockExecution")))}"> - <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=" AAI Update (vf module) " camunda:expression="${AAIUpdateTasks.updateOrchestrationStatusActivateVfModule(InjectExecution.execute(execution, execution.getVariable("gBuildingBlockExecution")))}"> <bpmn:incoming>SequenceFlow_1j4x1ej</bpmn:incoming> @@ -24,90 +25,167 @@ <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("gBuildingBlockExecution")))}"> + <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("gBuildingBlockExecution")))}"> + <bpmn:incoming>SequenceFlow_0ghzwlo</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_0xndboi</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:serviceTask id="Audit_AAI_Inventory" name="Validate A&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, "AuditAAIInventoryFailure", "Error Auditing Cloud Inventory in A&AI")}" 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("gBuildingBlockExecution")))}"> <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> diff --git a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CreateVfModuleBB.bpmn b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CreateVfModuleBB.bpmn index bd126de24e..08252f66b8 100644 --- a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CreateVfModuleBB.bpmn +++ b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CreateVfModuleBB.bpmn @@ -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("gBuildingBlockExecution")))}"> <bpmn:incoming>SequenceFlow_15hn8si</bpmn:incoming> @@ -34,15 +34,13 @@ <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=" AAI Update (vf module) " camunda:expression="${AAIUpdateTasks.updateOrchestrationStatusCreatedVfModule(InjectExecution.execute(execution, execution.getVariable("gBuildingBlockExecution")))}"> - <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=" AAI Update (vf module) " camunda:expression="${AAIUpdateTasks.updateHeatStackIdVfModule(InjectExecution.execute(execution, execution.getVariable("gBuildingBlockExecution")))}"> <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 " 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"> @@ -108,34 +108,20 @@ </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" /> @@ -159,6 +145,20 @@ <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> diff --git a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ExecuteBuildingBlock.bpmn b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ExecuteBuildingBlock.bpmn index 9be4cd0473..943ce12a8a 100644 --- a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ExecuteBuildingBlock.bpmn +++ b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ExecuteBuildingBlock.bpmn @@ -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 " 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)}"> @@ -114,6 +114,11 @@ </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"> @@ -156,63 +161,63 @@ </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" /> @@ -238,38 +243,38 @@ </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"> @@ -312,27 +317,27 @@ <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> diff --git a/bpmn/so-bpmn-building-blocks/src/test/java/org/onap/so/bpmn/BaseBPMNTest.java b/bpmn/so-bpmn-building-blocks/src/test/java/org/onap/so/bpmn/BaseBPMNTest.java index f501151ec9..79bade3cf3 100644 --- a/bpmn/so-bpmn-building-blocks/src/test/java/org/onap/so/bpmn/BaseBPMNTest.java +++ b/bpmn/so-bpmn-building-blocks/src/test/java/org/onap/so/bpmn/BaseBPMNTest.java @@ -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; @@ -94,6 +95,9 @@ public abstract class BaseBPMNTest { protected RuntimeService runtimeService; @Autowired + protected ExternalTaskService externalTaskService; + + @Autowired private RepositoryService repositoryService; protected Map<String, Object> variables = new HashMap<>(); @@ -227,6 +231,9 @@ public abstract class BaseBPMNTest { @MockBean protected WorkflowActionBBFailure workflowActionBBFailure; + + @MockBean + protected AuditTasks auditTasks; @LocalServerPort protected int port; diff --git a/bpmn/so-bpmn-building-blocks/src/test/java/org/onap/so/bpmn/infrastructure/bpmn/subprocess/ActivateVfModuleBBTest.java b/bpmn/so-bpmn-building-blocks/src/test/java/org/onap/so/bpmn/infrastructure/bpmn/subprocess/ActivateVfModuleBBTest.java index 1bce605076..9ffcd9d77a 100644 --- a/bpmn/so-bpmn-building-blocks/src/test/java/org/onap/so/bpmn/infrastructure/bpmn/subprocess/ActivateVfModuleBBTest.java +++ b/bpmn/so-bpmn-building-blocks/src/test/java/org/onap/so/bpmn/infrastructure/bpmn/subprocess/ActivateVfModuleBBTest.java @@ -21,9 +21,13 @@ 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"); } } diff --git a/bpmn/so-bpmn-building-blocks/src/test/resources/application-test.yaml b/bpmn/so-bpmn-building-blocks/src/test/resources/application-test.yaml index 1090ab7be4..c36172c3bf 100644 --- a/bpmn/so-bpmn-building-blocks/src/test/resources/application-test.yaml +++ b/bpmn/so-bpmn-building-blocks/src/test/resources/application-test.yaml @@ -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: diff --git a/bpmn/so-bpmn-building-blocks/src/test/resources/logback-test.xml b/bpmn/so-bpmn-building-blocks/src/test/resources/logback-test.xml index 64b6bfc81b..d8f6ba3930 100644 --- a/bpmn/so-bpmn-building-blocks/src/test/resources/logback-test.xml +++ b/bpmn/so-bpmn-building-blocks/src/test/resources/logback-test.xml @@ -26,5 +26,5 @@ </root> <logger name="wiremock.org" level="DEBUG" /> -<logger name="org.camunda" level="DEBUG" /> + </configuration>
\ No newline at end of file diff --git a/bpmn/so-bpmn-tasks/pom.xml b/bpmn/so-bpmn-tasks/pom.xml index becb66a6dc..0243ce8ae6 100644 --- a/bpmn/so-bpmn-tasks/pom.xml +++ b/bpmn/so-bpmn-tasks/pom.xml @@ -121,6 +121,11 @@ <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> <version>1.5.0-SNAPSHOT</version> 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 index 0000000000..aaa9e51d15 --- /dev/null +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/audit/AuditTasks.java @@ -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 index 0000000000..7a9e2bb6cf --- /dev/null +++ b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/audit/AuditTasksTest.java @@ -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)); + } +} diff --git a/common/src/main/java/org/onap/so/client/aai/AAIObjectPlurals.java b/common/src/main/java/org/onap/so/client/aai/AAIObjectPlurals.java index 12e0ebe691..7eadea00ff 100644 --- a/common/src/main/java/org/onap/so/client/aai/AAIObjectPlurals.java +++ b/common/src/main/java/org/onap/so/client/aai/AAIObjectPlurals.java @@ -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; diff --git a/common/src/main/java/org/onap/so/client/aai/AAIObjectType.java b/common/src/main/java/org/onap/so/client/aai/AAIObjectType.java index a6a9acfadd..66ff59d94f 100644 --- a/common/src/main/java/org/onap/so/client/aai/AAIObjectType.java +++ b/common/src/main/java/org/onap/so/client/aai/AAIObjectType.java @@ -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; diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/resources/application.yaml b/mso-api-handlers/mso-api-handler-infra/src/main/resources/application.yaml index a4c0c45fb3..41e024f625 100644 --- a/mso-api-handlers/mso-api-handler-infra/src/main/resources/application.yaml +++ b/mso-api-handlers/mso-api-handler-infra/src/main/resources/application.yaml @@ -7,6 +7,7 @@ server: mso: infra: + auditInventory: true default: versions: apiMinorVersion: 0 |