From 20873772d4ad9c13e07bebf35117f25b3312ed25 Mon Sep 17 00:00:00 2001 From: "Boslet, Cory" Date: Thu, 1 Oct 2020 16:41:57 -0400 Subject: Reworked how we find the sriov pf related link. Reworked how we find the sriov pf related link. Removed unneccessary line of code put in for test Issue-ID: SO-3282 Signed-off-by: Benjamin, Max (mb388a) Change-Id: Idfa54f4c9b3332ba325b4cc9fd0fc974c4e76d4f --- .../org/onap/so/heatbridge/HeatBridgeImpl.java | 116 ++++++++++----------- .../heatbridge/constants/HeatBridgeConstants.java | 1 + .../org/onap/so/heatbridge/HeatBridgeImplTest.java | 40 +++++-- .../test/resources/__files/pathed-sriov-pf.json | 8 ++ 4 files changed, 94 insertions(+), 71 deletions(-) create mode 100644 adapters/mso-openstack-adapters/src/test/resources/__files/pathed-sriov-pf.json diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java index 7d30c87101..5cb870e0d7 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java @@ -46,6 +46,7 @@ import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.ws.rs.NotFoundException; import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.UriBuilder; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.validator.routines.InetAddressValidator; import org.onap.aai.domain.yang.Flavor; @@ -59,7 +60,6 @@ import org.onap.aai.domain.yang.Pserver; import org.onap.aai.domain.yang.Relationship; import org.onap.aai.domain.yang.RelationshipList; import org.onap.aai.domain.yang.SriovPf; -import org.onap.aai.domain.yang.SriovPfs; import org.onap.aai.domain.yang.Subnets; import org.onap.aai.domain.yang.SriovVf; import org.onap.aai.domain.yang.VfModule; @@ -80,12 +80,12 @@ import org.onap.aaiclient.client.graphinventory.entities.DSLQuery; import org.onap.aaiclient.client.graphinventory.entities.DSLQueryBuilder; import org.onap.aaiclient.client.graphinventory.entities.DSLStartNode; import org.onap.aaiclient.client.graphinventory.entities.Node; +import org.onap.aaiclient.client.graphinventory.entities.Pathed; import org.onap.aaiclient.client.graphinventory.entities.Start; import org.onap.aaiclient.client.graphinventory.entities.TraversalBuilder; import org.onap.aaiclient.client.graphinventory.entities.__; import org.onap.aaiclient.client.graphinventory.entities.uri.Depth; import org.onap.aaiclient.client.graphinventory.exceptions.BulkProcessFailed; -import org.onap.logging.filter.base.ErrorCode; import org.onap.so.cloud.resource.beans.NodeType; import org.onap.so.db.catalog.beans.CloudIdentity; import org.onap.so.db.catalog.beans.ServerType; @@ -95,8 +95,6 @@ import org.onap.so.heatbridge.helpers.AaiHelper; import org.onap.so.heatbridge.openstack.api.OpenstackClient; import org.onap.so.heatbridge.openstack.factory.OpenstackClientFactoryImpl; import org.onap.so.heatbridge.utils.HeatBridgeUtils; -import org.onap.so.logger.LoggingAnchor; -import org.onap.so.logger.MessageEnum; import org.onap.so.spring.SpringContextHelper; import org.openstack4j.model.compute.Server; import org.openstack4j.model.heat.Resource; @@ -582,69 +580,67 @@ public class HeatBridgeImpl implements HeatBridgeApi { * * @param port Openstack port object * @param lIf AAI l-interface object + * @throws HeatBridgeException */ - private void updateSriovPfToPserver(final Port port, final LInterface lIf) { + protected void updateSriovPfToPserver(final Port port, final LInterface lIf) throws HeatBridgeException { if (port.getvNicType().equalsIgnoreCase(HeatBridgeConstants.OS_SRIOV_PORT_TYPE)) { - if (port.getProfile() == null || Strings - .isNullOrEmpty(port.getProfile().get(HeatBridgeConstants.OS_PHYSICAL_NETWORK_KEY).toString())) { - logger.debug("The SRIOV port:" + port.getName() + " is missing physical-network-id, cannot update " - + "sriov-pf object for host pserver: " + port.getHostId()); - return; - } - Optional matchingPifName = HeatBridgeUtils.getMatchingPserverPifName( - port.getProfile().get(HeatBridgeConstants.OS_PHYSICAL_NETWORK_KEY).toString()); - if (matchingPifName.isPresent()) { - // Update l-interface description - String pserverHostName = port.getHostId(); - lIf.setInterfaceDescription( - "Attached to SR-IOV port: " + pserverHostName + "::" + matchingPifName.get()); - try { - AAIResourceUri pInterfaceUri = - AAIUriFactory - .createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() - .pserver(pserverHostName).pInterface(matchingPifName.get())) - .depth(Depth.ONE); - if (resourcesClient.exists(pInterfaceUri)) { - PInterface matchingPIf = resourcesClient.get(PInterface.class, pInterfaceUri).get(); - - String pfPciId = port.getProfile().get(HeatBridgeConstants.OS_PCI_SLOT_KEY).toString(); - - if (matchingPIf.getSriovPfs() == null - || CollectionUtils.isEmpty(matchingPIf.getSriovPfs().getSriovPf()) - || matchingPIf.getSriovPfs().getSriovPf().stream() - .noneMatch(existingSriovPf -> existingSriovPf.getPfPciId().equals(pfPciId))) { - - SriovPf sriovPf = new SriovPf(); - sriovPf.setPfPciId(pfPciId); - - AAIResourceUri sriovPfUri = AAIUriFactory.createResourceUri( - AAIFluentTypeBuilder.cloudInfrastructure().pserver(pserverHostName) - .pInterface(matchingPifName.get()).sriovPf(sriovPf.getPfPciId())); - - // TODO if it does exist, should check if relationship is there, if not then create? - if (!resourcesClient.exists(sriovPfUri)) { - transaction.create(sriovPfUri, sriovPf); - - AAIResourceUri sriovVfUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder - .cloudInfrastructure().cloudRegion(cloudOwner, cloudRegionId).tenant(tenantId) - .vserver(port.getDeviceId()).lInterface(lIf.getInterfaceName()).sriovVf( - port.getProfile().get(HeatBridgeConstants.OS_PCI_SLOT_KEY).toString())); - transaction.connect(sriovPfUri, sriovVfUri); - } - } + + AAIResourceUri sriovVfUri = AAIUriFactory + .createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure().cloudRegion(cloudOwner, cloudRegionId) + .tenant(tenantId).vserver(port.getDeviceId()).lInterface(lIf.getInterfaceName()) + .sriovVf(port.getProfile().get(HeatBridgeConstants.OS_PCI_SLOT_KEY).toString())); + + boolean relationshipExist = sriovVfHasSriovPfRelationship(sriovVfUri); + + String pserverHostName = port.getHostId(); + lIf.setInterfaceDescription("Attached to SR-IOV port: " + pserverHostName); + + if (!relationshipExist) { + AAIResourceUri pserverUri = AAIUriFactory + .createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure().pserver(pserverHostName)); + if (resourcesClient.exists(pserverUri)) { + String pfPciId = port.getProfile().get(HeatBridgeConstants.OS_PF_PCI_SLOT_KEY).toString(); + + DSLQueryBuilder builder = TraversalBuilder + .fragment(new DSLStartNode(Types.PSERVER, __.key("hostname", pserverHostName))) + .to(__.node(Types.P_INTERFACE) + .to(__.node(Types.SRIOV_PF, __.key("pf-pci-id", pfPciId)).output())); + + List results = getAAIDSLClient().queryPathed(new DSLQuery(builder.build())); + + if (results.size() == 1) { + + AAIResourceUri sriovPfUri = AAIUriFactory.createResourceFromExistingURI(Types.SRIOV_PF, + UriBuilder.fromUri(results.get(0).getResourceLink()).build()); + + transaction.connect(sriovPfUri, sriovVfUri); + } else { - logger.warn( - "PInterface {} does not exist in AAI. Unable to build sriov-vf to sriov-pf relationship.", - matchingPifName.get()); + throw new HeatBridgeException("Unable to find sriov-pf related link " + pfPciId + + ". Unexpected results size" + results.size()); } - } catch (WebApplicationException e) { - // Silently log that we failed to update the Pserver p-interface with PCI-ID - logger.error(LoggingAnchor.NINE, MessageEnum.GENERAL_EXCEPTION, pserverHostName, - matchingPifName.get(), cloudOwner, tenantId, "OpenStack", "Heatbridge", - ErrorCode.DataError.getValue(), "Exception - Failed to add sriov-pf object to pserver", e); + } else { + logger.error("Pserver {} does not exist in AAI. Unable to build sriov-vf to sriov-pf relationship.", + pserverHostName); + throw new HeatBridgeException("Pserver " + pserverHostName + " does not exist in AAI"); + } + } + } + } + + protected boolean sriovVfHasSriovPfRelationship(AAIResourceUri sriovVfUri) { + boolean pfRelationshipsExist = false; + if (resourcesClient.exists(sriovVfUri)) { + Optional sriovVfRelationships = resourcesClient.get(sriovVfUri).getRelationships(); + + if (sriovVfRelationships.isPresent()) { + List sriovPfUris = sriovVfRelationships.get().getRelatedUris(Types.SRIOV_PF); + if (sriovPfUris.size() != 0) { + pfRelationshipsExist = true; } } } + return pfRelationshipsExist; } protected void updateLInterfaceIps(final Port port, final LInterface lIf) { diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/constants/HeatBridgeConstants.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/constants/HeatBridgeConstants.java index 71c6a96cd6..c8a39a5795 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/constants/HeatBridgeConstants.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/constants/HeatBridgeConstants.java @@ -43,6 +43,7 @@ public class HeatBridgeConstants { public static final String OS_NEUTRON_PROVIDERNET = "OS::Neutron::ProviderNet"; public static final String OS_SRIOV_PORT_TYPE = "direct"; public static final String OS_PCI_SLOT_KEY = "pci_slot"; + public static final String OS_PF_PCI_SLOT_KEY = "pf_pci_slot"; public static final String OS_PHYSICAL_NETWORK_KEY = "physical_network"; public static final String OS_PHYSICAL_INTERFACE_KEY = "physical-interface"; public static final String OS_VLAN_NETWORK_KEY = "vlan"; diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java index a9c31128ad..531496cc8f 100644 --- a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java +++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java @@ -42,6 +42,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -49,9 +50,10 @@ import static org.mockito.Mockito.when; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Objects; @@ -60,7 +62,6 @@ import java.util.Set; import org.apache.commons.io.FileUtils; import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -75,9 +76,12 @@ import org.onap.aai.domain.yang.SriovPf; import org.onap.aaiclient.client.aai.AAIDSLQueryClient; import org.onap.aaiclient.client.aai.AAIResourcesClient; import org.onap.aaiclient.client.aai.AAISingleTransactionClient; +import org.onap.aaiclient.client.aai.entities.Results; import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri; import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory; import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder; +import org.onap.aaiclient.client.graphinventory.entities.DSLQuery; +import org.onap.aaiclient.client.graphinventory.entities.Pathed; import org.onap.aaiclient.client.graphinventory.exceptions.BulkProcessFailed; import org.onap.so.cloud.resource.beans.NodeType; import org.onap.so.db.catalog.beans.CloudIdentity; @@ -100,6 +104,7 @@ import org.openstack4j.openstack.heat.domain.HeatResource; import org.openstack4j.openstack.heat.domain.HeatResource.Resources; import org.springframework.core.env.Environment; import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; @@ -133,6 +138,9 @@ public class HeatBridgeImplTest { @Mock private Server server; + @Mock + private AAIDSLQueryClient dSLQueryClient; + @Spy @InjectMocks private HeatBridgeImpl heatbridge = new HeatBridgeImpl(resourcesClient, cloudIdentity, CLOUD_OWNER, REGION_ID, @@ -342,11 +350,13 @@ public class HeatBridgeImplTest { } @Test - public void testUpdateVserverLInterfacesToAai() throws HeatBridgeException { + public void testUpdateVserverLInterfacesToAai() + throws HeatBridgeException, JsonParseException, JsonMappingException, IOException { // Arrange List stackResources = (List) extractTestStackResources(); Port port = mock(Port.class); when(port.getId()).thenReturn("test-port-id"); + when(port.getHostId()).thenReturn("pserverId"); when(port.getName()).thenReturn("test-port-name"); when(port.getvNicType()).thenReturn(HeatBridgeConstants.OS_SRIOV_PORT_TYPE); when(port.getMacAddress()).thenReturn("78:4f:43:68:e2:78"); @@ -357,7 +367,7 @@ public class HeatBridgeImplTest { when(server.getHypervisorHostname()).thenReturn("test.server.name"); String pfPciId = "0000:08:00.0"; when(port.getProfile()).thenReturn(ImmutableMap.of(HeatBridgeConstants.OS_PCI_SLOT_KEY, pfPciId, - HeatBridgeConstants.OS_PHYSICAL_NETWORK_KEY, "physical_network_id")); + HeatBridgeConstants.OS_PF_PCI_SLOT_KEY, "testPfPciId")); IP ip = mock(IP.class); @@ -386,10 +396,14 @@ public class HeatBridgeImplTest { SriovPf sriovPf = new SriovPf(); sriovPf.setPfPciId(pfPciId); - PInterface pIf = mock(PInterface.class); - when(pIf.getInterfaceName()).thenReturn("test-port-id"); - when(resourcesClient.get(eq(PInterface.class), any(AAIResourceUri.class))).thenReturn(Optional.of(pIf)); + + when(resourcesClient.exists(any(AAIResourceUri.class))).thenReturn(true); when(env.getProperty("mso.cloudOwner.included", "")).thenReturn("CloudOwner"); + doReturn(dSLQueryClient).when(heatbridge).getAAIDSLClient(); + List pathed = ((Results) MAPPER.readValue(getJson("pathed-sriov-pf.json"), + new TypeReference>() {})).getResult(); + when(dSLQueryClient.queryPathed(any(DSLQuery.class))).thenReturn(pathed); + doReturn(false).when(heatbridge).sriovVfHasSriovPfRelationship(any()); // Act heatbridge.buildAddVserverLInterfacesToAaiAction(stackResources, Arrays.asList("1", "2"), "CloudOwner"); @@ -399,6 +413,7 @@ public class HeatBridgeImplTest { verify(osClient, times(5)).getPortById(anyString()); verify(osClient, times(5)).getSubnetById("testSubnetId"); verify(osClient, times(10)).getNetworkById(anyString()); + verify(transaction, times(5)).connect(any(AAIResourceUri.class), any(AAIResourceUri.class)); } @Test @@ -571,7 +586,8 @@ public class HeatBridgeImplTest { } @Test - public void testUpdateVserverLInterfacesToAai_skipVlans() throws HeatBridgeException { + public void testUpdateVserverLInterfacesToAai_skipVlans() + throws HeatBridgeException, JsonParseException, JsonMappingException, IOException { // Arrange List stackResources = (List) extractTestStackResources(); Port port = mock(Port.class); @@ -597,11 +613,9 @@ public class HeatBridgeImplTest { when(osClient.getPortById("c54b9f45-b413-4937-bbe4-3c8a5689cfc9")).thenReturn(port); when(osClient.getNetworkById(anyString())).thenReturn(network); - SriovPf sriovPf = new SriovPf(); - sriovPf.setPfPciId(pfPciId); PInterface pIf = mock(PInterface.class); when(pIf.getInterfaceName()).thenReturn("test-port-id"); - when(resourcesClient.get(eq(PInterface.class), any(AAIResourceUri.class))).thenReturn(Optional.of(pIf)); + doNothing().when(heatbridge).updateSriovPfToPserver(any(), any()); // Act heatbridge.buildAddVserverLInterfacesToAaiAction(stackResources, Arrays.asList("1", "2"), "CloudOwner"); @@ -636,5 +650,9 @@ public class HeatBridgeImplTest { return content; } + private String getJson(String filename) throws IOException { + return new String(Files.readAllBytes(Paths.get("src/test/resources/__files/" + filename))); + } + } diff --git a/adapters/mso-openstack-adapters/src/test/resources/__files/pathed-sriov-pf.json b/adapters/mso-openstack-adapters/src/test/resources/__files/pathed-sriov-pf.json new file mode 100644 index 0000000000..cccad4c6d3 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/resources/__files/pathed-sriov-pf.json @@ -0,0 +1,8 @@ +{ + "results" : [ + { + "resource-type" : "sriov-pf", + "resource-link" : "/cloud-infrastructure/pservers/pserver/id1/p-interfaces/p-interface/id2/sriov-pfs/sriov-pf/id3" + } + ] +} \ No newline at end of file -- cgit 1.2.3-korg