summaryrefslogtreecommitdiffstats
path: root/adapters/mso-openstack-adapters/src
diff options
context:
space:
mode:
authorBenjamin, Max (mb388a) <mb388a@us.att.com>2019-02-01 18:13:35 -0500
committerBenjamin, Max (mb388a) <mb388a@us.att.com>2019-02-01 18:48:10 -0500
commit4e63348e5b0c9b8df287ee6eba33b69ffd5f2516 (patch)
treea6d806d3185efc62ff8af71bb572c02550aea2a2 /adapters/mso-openstack-adapters/src
parent62572d10fe5ea77726371c624b6bcbb33ff1707b (diff)
compare resources from openstack to aai
Address Review comments on pull request Update Unit test to have proper variable for testing update logic inside bpmn to reflect proper variable Update unit test to check property for audit Add flag to turn on and off audit behavior Add license headers, remove un-used files Update Building Block Tests and Activity Names Fix additional unit tests in so-bpmn-tasks layer Fix broken Junit Test, and correct Bug in if statement Add annotation to ignore class under test profile Additional bug fixes and unit tests for classes Add Additional JUNITS, add more sample data Add Openstack Audit functionality to Adapter Change-Id: I0492063271e991eefc608b56336a5cdf1d5a7778 Issue-ID: SO-1456 Signed-off-by: Benjamin, Max (mb388a) <mb388a@us.att.com>
Diffstat (limited to 'adapters/mso-openstack-adapters/src')
-rw-r--r--adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AbstractAudit.java39
-rw-r--r--adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackService.java68
-rw-r--r--adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackServiceData.java86
-rw-r--r--adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditVServer.java111
-rw-r--r--adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/HeatStackAudit.java199
-rw-r--r--adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/AaiClientPropertiesImpl.java69
-rw-r--r--adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/MsoOpenstackAdaptersApplication.java2
-rw-r--r--adapters/mso-openstack-adapters/src/main/resources/META-INF/services/org.onap.so.client.RestProperties1
-rw-r--r--adapters/mso-openstack-adapters/src/main/resources/application.yaml4
-rw-r--r--adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/AuditStackServiceDataTest.java150
-rw-r--r--adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/AuditVServerTest.java332
-rw-r--r--adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/HeatStackAuditTest.java241
-rw-r--r--adapters/mso-openstack-adapters/src/test/resources/AVPNResourceGroupResponse.json79
-rw-r--r--adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface0.json41
-rw-r--r--adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface0Resources.json72
-rw-r--r--adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface1.json43
-rw-r--r--adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface1Resources.json72
-rw-r--r--adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface2.json41
-rw-r--r--adapters/mso-openstack-adapters/src/test/resources/AVPNSubInterface2Resources.json72
-rw-r--r--adapters/mso-openstack-adapters/src/test/resources/GetResources.json206
-rw-r--r--adapters/mso-openstack-adapters/src/test/resources/MISResourceGroupResponse.json31
-rw-r--r--adapters/mso-openstack-adapters/src/test/resources/MISSubInterface0.json41
-rw-r--r--adapters/mso-openstack-adapters/src/test/resources/MISSubInterface1Resources.json70
-rw-r--r--adapters/mso-openstack-adapters/src/test/resources/logback-test.xml6
24 files changed, 2074 insertions, 2 deletions
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>