From 634486887a78da4c897389955d6dfa77bc795be6 Mon Sep 17 00:00:00 2001 From: Marek Gradzki Date: Wed, 22 Jun 2016 12:57:07 +0200 Subject: HONEYCOMB-95: remove sub-interfaces from the list of interfaces Change-Id: I3a22bbfd49a5e3c1519526a98e8841807553710b Signed-off-by: Marek Gradzki --- .../v3po/interfacesstate/InterfaceCustomizer.java | 90 ++++++++++++---------- .../interfacesstate/InterfaceCustomizerTest.java | 58 ++++++++++---- 2 files changed, 95 insertions(+), 53 deletions(-) (limited to 'v3po/v3po2vpp') diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java index 18079e6e4..943016aac 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java @@ -23,6 +23,13 @@ import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer; import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer; import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext; import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesStateBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus; @@ -40,23 +47,15 @@ import org.openvpp.jvpp.future.FutureJVpp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nonnull; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; - /** * Customizer for reading ietf-interfaces:interfaces-state/interface. */ public class InterfaceCustomizer extends FutureJVppCustomizer - implements ListReaderCustomizer { + implements ListReaderCustomizer { private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class); public static final String DUMPED_IFCS_CONTEXT_KEY = - InterfaceCustomizer.class.getName() + "dumpedInterfacesDuringGetAllIds"; + InterfaceCustomizer.class.getName() + "dumpedInterfacesDuringGetAllIds"; private final NamingContext interfaceContext; @@ -75,38 +74,43 @@ public class InterfaceCustomizer extends FutureJVppCustomizer public void readCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull InterfaceBuilder builder, @Nonnull ReadContext ctx) throws ReadFailedException { LOG.debug("Reading attributes for interface: {}", id); - final InterfaceKey key = id.firstKeyOf(id.getTargetType()); + final String ifaceName = id.firstKeyOf(id.getTargetType()).getName(); // Pass cached details from getAllIds to getDetails to avoid additional dumps - final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), id, key.getName(), - interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache()); - LOG.debug("Interface details for interface: {}, details: {}", key.getName(), iface); + final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), id, ifaceName, + interfaceContext.getIndex(ifaceName, ctx.getMappingContext()), ctx.getModificationCache()); + LOG.debug("Interface details for interface: {}, details: {}", ifaceName, iface); - builder.setName(key.getName()); + if (!isRegularInterface(iface)) { + LOG.debug("Interface: {} is a sub-interface. Ignoring read request.", ifaceName); + return; + } + + builder.setName(ifaceName); builder.setType(InterfaceUtils.getInterfaceType(new String(iface.interfaceName).intern())); builder.setIfIndex(InterfaceUtils.vppIfIndexToYang(iface.swIfIndex)); builder.setAdminStatus(1 == iface.adminUpDown - ? AdminStatus.Up - : AdminStatus.Down); + ? AdminStatus.Up + : AdminStatus.Down); builder.setOperStatus(1 == iface.linkUpDown - ? OperStatus.Up - : OperStatus.Down); + ? OperStatus.Up + : OperStatus.Down); if (0 != iface.linkSpeed) { builder.setSpeed(InterfaceUtils.vppInterfaceSpeedToYang(iface.linkSpeed)); } if (iface.l2AddressLength == 6) { builder.setPhysAddress(new PhysAddress(InterfaceUtils.vppPhysAddrToYang(iface.l2Address))); } - LOG.trace("Base attributes read for interface: {} as: {}", key.getName(), builder); + LOG.trace("Base attributes read for interface: {} as: {}", ifaceName, builder); } @Nonnull @SuppressWarnings("unchecked") public static Map getCachedInterfaceDump(@Nonnull final ModificationCache ctx) { return ctx.get(DUMPED_IFCS_CONTEXT_KEY) == null - ? new HashMap<>() - // allow customizers to update the cache - : (Map) ctx.get(DUMPED_IFCS_CONTEXT_KEY); + ? new HashMap<>() + // allow customizers to update the cache + : (Map) ctx.get(DUMPED_IFCS_CONTEXT_KEY); } @Nonnull @@ -122,9 +126,9 @@ public class InterfaceCustomizer extends FutureJVppCustomizer request.nameFilterValid = 0; final CompletableFuture swInterfaceDetailsReplyDumpCompletableFuture = - getFutureJVpp().swInterfaceDump(request).toCompletableFuture(); + getFutureJVpp().swInterfaceDump(request).toCompletableFuture(); final SwInterfaceDetailsReplyDump ifaces = - TranslateUtils.getReply(swInterfaceDetailsReplyDumpCompletableFuture); + TranslateUtils.getReply(swInterfaceDetailsReplyDumpCompletableFuture); if (null == ifaces || null == ifaces.swInterfaceDetails) { LOG.debug("No interfaces for :{} found in VPP", id); @@ -133,23 +137,25 @@ public class InterfaceCustomizer extends FutureJVppCustomizer // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes context.getModificationCache().put(DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream() - .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails))); + .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails))); interfacesKeys = ifaces.swInterfaceDetails.stream() - .filter(elt -> elt != null) - .map((elt) -> { - // Store interface name from VPP in context if not yet present - if (!interfaceContext.containsName(elt.swIfIndex, context.getMappingContext())) { - interfaceContext.addName(elt.swIfIndex, TranslateUtils.toString(elt.interfaceName), - context.getMappingContext()); - } - LOG.trace("Interface with name: {}, VPP name: {} and index: {} found in VPP", - interfaceContext.getName(elt.swIfIndex, context.getMappingContext()), elt.interfaceName, - elt.swIfIndex); - - return new InterfaceKey(interfaceContext.getName(elt.swIfIndex, context.getMappingContext())); - }) - .collect(Collectors.toList()); + .filter(elt -> elt != null) + .map((elt) -> { + // Store interface name from VPP in context if not yet present + if (!interfaceContext.containsName(elt.swIfIndex, context.getMappingContext())) { + interfaceContext.addName(elt.swIfIndex, TranslateUtils.toString(elt.interfaceName), + context.getMappingContext()); + } + LOG.trace("Interface with name: {}, VPP name: {} and index: {} found in VPP", + interfaceContext.getName(elt.swIfIndex, context.getMappingContext()), elt.interfaceName, + elt.swIfIndex); + + return elt; + }) + .filter(InterfaceCustomizer::isRegularInterface) // filter out sub-interfaces + .map((elt) -> new InterfaceKey(interfaceContext.getName(elt.swIfIndex, context.getMappingContext()))) + .collect(Collectors.toList()); LOG.debug("Interfaces found in VPP: {}", interfacesKeys); return interfacesKeys; @@ -159,6 +165,10 @@ public class InterfaceCustomizer extends FutureJVppCustomizer } } + private static boolean isRegularInterface(final SwInterfaceDetails iface) { + return iface.subId == 0; + } + @Override public void merge(@Nonnull final org.opendaylight.yangtools.concepts.Builder builder, @Nonnull final List readData) { diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java index 1e5dad7d1..dc2d3b675 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; import com.google.common.base.Optional; import com.google.common.collect.Lists; @@ -54,7 +55,7 @@ import org.openvpp.jvpp.dto.SwInterfaceDetails; import org.openvpp.jvpp.dto.SwInterfaceDump; public class InterfaceCustomizerTest extends - ListReaderCustomizerTest { + ListReaderCustomizerTest { private NamingContext interfacesContext; @@ -71,15 +72,19 @@ public class InterfaceCustomizerTest extends protected RootReaderCustomizer initCustomizer() { final KeyedInstanceIdentifier eth0Id = getMappingIid("eth0", "test-instance"); final KeyedInstanceIdentifier eth1Id = getMappingIid("eth1", "test-instance"); + final KeyedInstanceIdentifier subEth1Id = getMappingIid("eth1.1", "test-instance"); final Optional eth0 = getMapping("eth0", 0); final Optional eth1 = getMapping("eth1", 1); + final Optional subEth1 = getMapping("eth1.1", 2); - final List allMappings = Lists.newArrayList(getMapping("eth0", 0).get(), getMapping("eth1", 1).get()); + final List allMappings = + Lists.newArrayList(getMapping("eth0", 0).get(), getMapping("eth1", 1).get(), getMapping("eth1.1", 2).get()); final Mappings allMappingsBaObject = new MappingsBuilder().setMapping(allMappings).build(); doReturn(Optional.of(allMappingsBaObject)).when(mappingContext).read(eth0Id.firstIdentifierOf(Mappings.class)); doReturn(eth0).when(mappingContext).read(eth0Id); doReturn(eth1).when(mappingContext).read(eth1Id); + doReturn(subEth1).when(mappingContext).read(subEth1Id); return new InterfaceCustomizer(api, interfacesContext); } @@ -93,8 +98,9 @@ public class InterfaceCustomizerTest extends verify(builder).setInterface(value); } - private void verifyBridgeDomainDumpUpdateWasInvoked(final int nameFilterValid, final String ifaceName, - final int dumpIfcsInvocationCount) throws VppInvocationException { + private void verifySwInterfaceDumpWasInvoked(final int nameFilterValid, final String ifaceName, + final int dumpIfcsInvocationCount) + throws VppInvocationException { // TODO adding equals methods for jvpp DTOs would make ArgumentCaptor usage obsolete ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(SwInterfaceDump.class); verify(api, times(dumpIfcsInvocationCount)).swInterfaceDump(argumentCaptor.capture()); @@ -109,13 +115,11 @@ public class InterfaceCustomizerTest extends assertEquals(iface.getPhysAddress().getValue(), InterfaceUtils.vppPhysAddrToYang(details.l2Address)); } - - @Test public void testReadCurrentAttributes() throws Exception { final String ifaceName = "eth0"; final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class, new InterfaceKey(ifaceName)); + .child(Interface.class, new InterfaceKey(ifaceName)); final InterfaceBuilder builder = getCustomizer().getBuilder(id); final SwInterfaceDetails iface = new SwInterfaceDetails(); @@ -129,7 +133,7 @@ public class InterfaceCustomizerTest extends getCustomizer().readCurrentAttributes(id, builder, ctx); - verifyBridgeDomainDumpUpdateWasInvoked(1, ifaceName, 1); + verifySwInterfaceDumpWasInvoked(1, ifaceName, 1); assertIfacesAreEqual(builder.build(), iface); } @@ -137,7 +141,7 @@ public class InterfaceCustomizerTest extends public void testReadCurrentAttributesFailed() throws Exception { final String ifaceName = "eth0"; final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class, new InterfaceKey(ifaceName)); + .child(Interface.class, new InterfaceKey(ifaceName)); final InterfaceBuilder builder = getCustomizer().getBuilder(id); whenSwInterfaceDumpThenReturn(api, Collections.emptyList()); @@ -145,17 +149,38 @@ public class InterfaceCustomizerTest extends try { getCustomizer().readCurrentAttributes(id, builder, ctx); } catch (IllegalArgumentException e) { - verifyBridgeDomainDumpUpdateWasInvoked(0, ifaceName, 2); + verifySwInterfaceDumpWasInvoked(0, ifaceName, 2); return; } fail("ReadFailedException was expected"); } + @Test + public void testReadSubInterface() throws Exception { + final String ifaceName = "eth1.1"; + final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) + .child(Interface.class, new InterfaceKey(ifaceName)); + final InterfaceBuilder builder = mock(InterfaceBuilder.class); + + final SwInterfaceDetails iface = new SwInterfaceDetails(); + iface.interfaceName = ifaceName.getBytes(); + iface.swIfIndex = 2; + iface.supSwIfIndex = 1; + iface.subId = 1; + final List interfaceList = Collections.singletonList(iface); + whenSwInterfaceDumpThenReturn(api, interfaceList); + + getCustomizer().readCurrentAttributes(id, builder, ctx); + + verifySwInterfaceDumpWasInvoked(1, ifaceName, 1); + verifyZeroInteractions(builder); + } + @Test public void testGetAllIds() throws Exception { final InstanceIdentifier id = InstanceIdentifier.create(InterfacesState.class) - .child(Interface.class); + .child(Interface.class); final String swIf0Name = "eth0"; final SwInterfaceDetails swIf0 = new SwInterfaceDetails(); @@ -165,13 +190,20 @@ public class InterfaceCustomizerTest extends final SwInterfaceDetails swIf1 = new SwInterfaceDetails(); swIf1.swIfIndex = 1; swIf1.interfaceName = swIf1Name.getBytes(); - whenSwInterfaceDumpThenReturn(api, Arrays.asList(swIf0, swIf1)); + final String swSubIf1Name = "eth1.1"; + final SwInterfaceDetails swSubIf1 = new SwInterfaceDetails(); + swSubIf1.swIfIndex = 2; + swSubIf1.subId = 1; + swSubIf1.supSwIfIndex = 1; + swSubIf1.interfaceName = swSubIf1Name.getBytes(); + whenSwInterfaceDumpThenReturn(api, Arrays.asList(swIf0, swIf1, swSubIf1)); final List expectedIds = Arrays.asList(new InterfaceKey(swIf0Name), new InterfaceKey(swIf1Name)); final List actualIds = getCustomizer().getAllIds(id, ctx); - verifyBridgeDomainDumpUpdateWasInvoked(0, "", 1); + verifySwInterfaceDumpWasInvoked(0, "", 1); + // sub-interface should not be on the list assertEquals(expectedIds, actualIds); } } -- cgit 1.2.3-korg