diff options
author | Jan Srnicek <jsrnicek@cisco.com> | 2017-08-15 10:15:06 +0200 |
---|---|---|
committer | Marek Gradzki <mgradzki@cisco.com> | 2017-08-16 05:37:09 +0000 |
commit | b1b07f942fd77b7d987cc44aabd492db5e8c29a0 (patch) | |
tree | bca9afe1e431c7287600c6fd5daa851dc70d3967 /v3po/v3po2vpp/src/main/java/io/fd | |
parent | be31f4746e6ee61dbe448ce0d49b8236bdbcc6f8 (diff) |
HC2VPP-205 / HC2VPP-25 - Sub interface caching improvement
Improves dumping mechanism for sub interfaces in a way
that if full dump was already performed,
it will be used from cache instead of new dump call.
Also prevents creating dump dto's if not necessary
Change-Id: I46a305ec1b325c2d949bff9e2b151752ccd508b6
Signed-off-by: Jan Srnicek <jsrnicek@cisco.com>
Diffstat (limited to 'v3po/v3po2vpp/src/main/java/io/fd')
20 files changed, 598 insertions, 363 deletions
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java index fb8911088..b12893955 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java @@ -17,6 +17,7 @@ package io.fd.hc2vpp.v3po; import com.google.inject.AbstractModule; +import com.google.inject.Singleton; import com.google.inject.multibindings.Multibinder; import com.google.inject.name.Names; import io.fd.hc2vpp.common.translate.util.NamingContext; @@ -26,6 +27,8 @@ import io.fd.hc2vpp.v3po.factory.L2HoneycombWriterFactory; import io.fd.hc2vpp.v3po.factory.L2StateHoneycombReaderFactory; import io.fd.hc2vpp.v3po.factory.SubinterfaceAugmentationWriterFactory; import io.fd.hc2vpp.v3po.factory.SubinterfaceStateAugmentationReaderFactory; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManagerProvider; import io.fd.hc2vpp.v3po.notification.InterfaceChangeNotificationProducerProvider; import io.fd.honeycomb.notification.ManagedNotificationProducer; import io.fd.honeycomb.translate.read.ReaderFactory; @@ -50,6 +53,8 @@ public class V3poModule extends AbstractModule { .annotatedWith(Names.named("bridge-domain-context")) .toInstance(new NamingContext("bridge-domain-", "bridge-domain-context")); + bind(InterfaceCacheDumpManager.class).toProvider(InterfaceCacheDumpManagerProvider.class).in(Singleton.class); + // Context utility for deleted interfaces bind(DisabledInterfacesManager.class).toInstance(new DisabledInterfacesManager()); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesStateReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesStateReaderFactory.java index 44390b41d..eaacb135a 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesStateReaderFactory.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesStateReaderFactory.java @@ -30,6 +30,7 @@ import io.fd.hc2vpp.v3po.interfacesstate.TapCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.VhostUserCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.VxlanCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.VxlanGpeCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; import io.fd.hc2vpp.v3po.interfacesstate.pbb.PbbRewriteStateCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.span.InterfaceMirroredInterfacesCustomizer; import io.fd.honeycomb.translate.impl.read.GenericInitListReader; @@ -65,6 +66,7 @@ public final class InterfacesStateReaderFactory implements ReaderFactory { private final NamingContext ifcNamingCtx; private final NamingContext bdNamingCtx; private final DisabledInterfacesManager ifcDisableContext; + private final InterfaceCacheDumpManager ifaceDumpManager; private final FutureJVppCore jvpp; static final InstanceIdentifier<InterfacesState> IFC_STATE_ID = @@ -75,11 +77,13 @@ public final class InterfacesStateReaderFactory implements ReaderFactory { public InterfacesStateReaderFactory(final FutureJVppCore jvpp, @Named("interface-context") final NamingContext ifcNamingCtx, @Named("bridge-domain-context") final NamingContext bdNamingCtx, - final DisabledInterfacesManager ifcDisableContext) { + final DisabledInterfacesManager ifcDisableContext, + final InterfaceCacheDumpManager ifaceDumpManager) { this.jvpp = jvpp; this.ifcNamingCtx = ifcNamingCtx; this.bdNamingCtx = bdNamingCtx; this.ifcDisableContext = ifcDisableContext; + this.ifaceDumpManager = ifaceDumpManager; } @Override @@ -87,7 +91,8 @@ public final class InterfacesStateReaderFactory implements ReaderFactory { // InterfacesState(Structural) registry.addStructuralReader(IFC_STATE_ID, InterfacesStateBuilder.class); // Interface - registry.add(new GenericInitListReader<>(IFC_ID, new InterfaceCustomizer(jvpp, ifcNamingCtx, ifcDisableContext))); + registry.add(new GenericInitListReader<>(IFC_ID, + new InterfaceCustomizer(ifcNamingCtx, ifcDisableContext, ifaceDumpManager))); // v3po.yang initVppIfcAugmentationReaders(registry, IFC_ID); @@ -104,25 +109,28 @@ public final class InterfacesStateReaderFactory implements ReaderFactory { registry.addStructuralReader(vppIfcAugId, VppInterfaceStateAugmentationBuilder.class); // Ethernet registry.add(new GenericInitReader<>(vppIfcAugId.child(Ethernet.class), - new EthernetCustomizer(jvpp, ifcNamingCtx))); + new EthernetCustomizer(ifaceDumpManager))); // Routing registry.add(new GenericInitReader<>(vppIfcAugId.child(Routing.class), - new InterfaceRoutingCustomizer(jvpp, ifcNamingCtx))); + new InterfaceRoutingCustomizer(jvpp, ifcNamingCtx))); // Tap - registry.add(new GenericInitReader<>(vppIfcAugId.child(Tap.class), new TapCustomizer(jvpp, ifcNamingCtx))); + registry.add(new GenericInitReader<>(vppIfcAugId.child(Tap.class), + new TapCustomizer(jvpp, ifcNamingCtx, ifaceDumpManager))); // VhostUser registry.add(new GenericInitReader<>(vppIfcAugId.child(VhostUser.class), - new VhostUserCustomizer(jvpp, ifcNamingCtx))); + new VhostUserCustomizer(jvpp, ifcNamingCtx, ifaceDumpManager))); // Vxlan - registry.add(new GenericInitReader<>(vppIfcAugId.child(Vxlan.class), new VxlanCustomizer(jvpp, ifcNamingCtx))); + registry.add(new GenericInitReader<>(vppIfcAugId.child(Vxlan.class), + new VxlanCustomizer(jvpp, ifcNamingCtx, ifaceDumpManager))); // VxlanGpe registry.add(new GenericInitReader<>(vppIfcAugId.child(VxlanGpe.class), - new VxlanGpeCustomizer(jvpp, ifcNamingCtx))); + new VxlanGpeCustomizer(jvpp, ifcNamingCtx, ifaceDumpManager))); // Gre - registry.add(new GenericInitReader<>(vppIfcAugId.child(Gre.class), new GreCustomizer(jvpp, ifcNamingCtx))); + registry.add(new GenericInitReader<>(vppIfcAugId.child(Gre.class), + new GreCustomizer(jvpp, ifcNamingCtx, ifaceDumpManager))); // L2 registry.add(new GenericInitReader<>(vppIfcAugId.child(L2.class), - new L2Customizer(jvpp, ifcNamingCtx, bdNamingCtx))); + new L2Customizer(jvpp, ifcNamingCtx, bdNamingCtx, ifaceDumpManager))); // Span final InstanceIdentifier<Span> spanId = vppIfcAugId.child(Span.class); registry.addStructuralReader(spanId, SpanBuilder.class); @@ -141,5 +149,4 @@ public final class InterfacesStateReaderFactory implements ReaderFactory { registry.add(new GenericReader<>(ifcId.augmentation(PbbRewriteStateInterfaceAugmentation.class).child( PbbRewriteState.class), new PbbRewriteStateCustomizer(jvpp))); } - } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceStateAugmentationReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceStateAugmentationReaderFactory.java index de91a067b..a041bc820 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceStateAugmentationReaderFactory.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceStateAugmentationReaderFactory.java @@ -24,6 +24,7 @@ import io.fd.hc2vpp.v3po.interfacesstate.RewriteCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.SubInterfaceCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.SubInterfaceL2Customizer; import io.fd.hc2vpp.v3po.interfacesstate.SubInterfaceRoutingCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; import io.fd.hc2vpp.v3po.interfacesstate.span.SubInterfaceMirroredInterfacesCustomizer; import io.fd.honeycomb.translate.impl.read.GenericInitListReader; import io.fd.honeycomb.translate.impl.read.GenericInitReader; @@ -36,7 +37,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.subinter import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.subinterface.span.rev170607.VppSubinterfaceSpanStateAugmentationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.subinterface.span.rev170607.interfaces.state._interface.sub.interfaces.sub._interface.SpanState; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.subinterface.span.rev170607.interfaces.state._interface.sub.interfaces.sub._interface.SpanStateBuilder; - import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.span.state.attributes.MirroredInterfaces; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.SubinterfaceStateAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.SubinterfaceStateAugmentationBuilder; @@ -45,12 +45,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.interfaces.state._interface.sub.interfaces.SubInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.match.attributes.match.type.vlan.tagged.VlanTagged; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.rewrite.attributes.Rewrite; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.sub._interface.l2.state.attributes.L2; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.sub._interface.base.attributes.Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.sub._interface.base.attributes.Tags; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.sub._interface.base.attributes.tags.Tag; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.sub._interface.l2.state.attributes.L2; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.sub._interface.routing.attributes.Routing; - import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.tag.rewrite.PushTags; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -59,21 +58,24 @@ public final class SubinterfaceStateAugmentationReaderFactory implements ReaderF private final FutureJVppCore jvpp; private final NamingContext ifcCtx; private final NamingContext bdCtx; + private final InterfaceCacheDumpManager ifaceDumpManager; @Inject public SubinterfaceStateAugmentationReaderFactory(final FutureJVppCore jvpp, @Named("interface-context") final NamingContext ifcCtx, - @Named("bridge-domain-context") final NamingContext bdCtx) { + @Named("bridge-domain-context") final NamingContext bdCtx, + final InterfaceCacheDumpManager ifaceDumpManager) { this.jvpp = jvpp; this.ifcCtx = ifcCtx; this.bdCtx = bdCtx; + this.ifaceDumpManager = ifaceDumpManager; } @Override public void init(final ModifiableReaderRegistryBuilder registry) { // SubinterfaceStateAugmentation(Structural) final InstanceIdentifier<SubinterfaceStateAugmentation> subIfcAugId = - InterfacesStateReaderFactory.IFC_ID.augmentation(SubinterfaceStateAugmentation.class); + InterfacesStateReaderFactory.IFC_ID.augmentation(SubinterfaceStateAugmentation.class); registry.addStructuralReader(subIfcAugId, SubinterfaceStateAugmentationBuilder.class); // SubInterfaces(Structural) final InstanceIdentifier<SubInterfaces> subIfcsId = subIfcAugId.child(SubInterfaces.class); @@ -81,26 +83,30 @@ public final class SubinterfaceStateAugmentationReaderFactory implements ReaderF // SubInterface(Subtree) final InstanceIdentifier<SubInterface> subIfcId = subIfcsId.child(SubInterface.class); registry.subtreeAdd(Sets.newHashSet( - InstanceIdentifier.create(SubInterface.class).child(Tags.class), - InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class), - InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class).child(Dot1qTag.class), - InstanceIdentifier.create(SubInterface.class).child(Match.class), - InstanceIdentifier.create(SubInterface.class).child(Match.class).child(VlanTagged.class)), - new GenericInitListReader<>(subIfcId, new SubInterfaceCustomizer(jvpp, ifcCtx))); + InstanceIdentifier.create(SubInterface.class).child(Tags.class), + InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class), + InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class).child(Dot1qTag.class), + InstanceIdentifier.create(SubInterface.class).child(Match.class), + InstanceIdentifier.create(SubInterface.class).child(Match.class).child(VlanTagged.class)), + new GenericInitListReader<>(subIfcId, + new SubInterfaceCustomizer(jvpp, ifcCtx, ifaceDumpManager))); // L2 final InstanceIdentifier<L2> l2Id = subIfcId.child(L2.class); - registry.add(new GenericInitReader<>(l2Id, new SubInterfaceL2Customizer(jvpp, ifcCtx, bdCtx))); + registry.add(new GenericInitReader<>(l2Id, + new SubInterfaceL2Customizer(jvpp, ifcCtx, bdCtx, ifaceDumpManager))); // Rewrite(Subtree) registry.subtreeAdd(Sets.newHashSet( - InstanceIdentifier.create(Rewrite.class).child(PushTags.class), - InstanceIdentifier.create(Rewrite.class).child(PushTags.class) - .child( - org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.Dot1qTag.class)), - new GenericReader<>(l2Id.child(Rewrite.class), new RewriteCustomizer(jvpp, ifcCtx))); + InstanceIdentifier.create(Rewrite.class).child(PushTags.class), + InstanceIdentifier.create(Rewrite.class).child(PushTags.class) + .child( + org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.Dot1qTag.class)), + new GenericReader<>(l2Id.child(Rewrite.class), + new RewriteCustomizer(ifaceDumpManager))); final InstanceIdentifier<Routing> routingId = subIfcId.child(Routing.class); registry.add(new GenericReader<>(routingId, new SubInterfaceRoutingCustomizer(jvpp, ifcCtx))); - final InstanceIdentifier<VppSubinterfaceSpanStateAugmentation> spanStateAugId = subIfcId.augmentation(VppSubinterfaceSpanStateAugmentation.class); + final InstanceIdentifier<VppSubinterfaceSpanStateAugmentation> spanStateAugId = + subIfcId.augmentation(VppSubinterfaceSpanStateAugmentation.class); registry.addStructuralReader(spanStateAugId, VppSubinterfaceSpanStateAugmentationBuilder.class); final InstanceIdentifier<SpanState> spanStateId = spanStateAugId @@ -108,6 +114,7 @@ public final class SubinterfaceStateAugmentationReaderFactory implements ReaderF registry.addStructuralReader(spanStateId, SpanStateBuilder.class); final InstanceIdentifier<MirroredInterfaces> mirroredInterfacesId = spanStateId.child(MirroredInterfaces.class); - registry.add(new GenericInitReader<>(mirroredInterfacesId, new SubInterfaceMirroredInterfacesCustomizer(jvpp, ifcCtx))); + registry.add(new GenericInitReader<>(mirroredInterfacesId, + new SubInterfaceMirroredInterfacesCustomizer(jvpp, ifcCtx))); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/EthernetCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/EthernetCustomizer.java index 1afdbcd37..8bb01a98b 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/EthernetCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/EthernetCustomizer.java @@ -16,15 +16,13 @@ package io.fd.hc2vpp.v3po.interfacesstate; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.Initialized; import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; import javax.annotation.Nonnull; 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.InterfaceKey; @@ -35,20 +33,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -public class EthernetCustomizer extends FutureJVppCustomizer +public class EthernetCustomizer implements InitializingReaderCustomizer<Ethernet, EthernetBuilder>, InterfaceDataTranslator { - private static final Logger LOG = LoggerFactory.getLogger(EthernetCustomizer.class); - private NamingContext interfaceContext; + private final InterfaceCacheDumpManager dumpManager; - public EthernetCustomizer(@Nonnull final FutureJVppCore jvpp, - @Nonnull final NamingContext interfaceContext) { - super(jvpp); - this.interfaceContext = interfaceContext; + public EthernetCustomizer(@Nonnull final InterfaceCacheDumpManager dumpManager) { + this.dumpManager = dumpManager; } @Override @@ -69,8 +62,7 @@ public class EthernetCustomizer extends FutureJVppCustomizer @Nonnull final ReadContext ctx) throws ReadFailedException { final InterfaceKey key = id.firstKeyOf(Interface.class); - final SwInterfaceDetails iface = getVppInterfaceDetails(getFutureJVpp(), id, key.getName(), - interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache(), LOG); + final SwInterfaceDetails iface = dumpManager.getInterfaceDetail(id, ctx, key.getName()); if (iface.linkMtu != 0) { builder.setMtu((int) iface.linkMtu); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizer.java index 3d1782a1e..ee54a110f 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizer.java @@ -18,13 +18,14 @@ package io.fd.hc2vpp.v3po.interfacesstate; import static com.google.common.base.Preconditions.checkState; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.Initialized; import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.vpp.jvpp.core.dto.GreTunnelDetails; import io.fd.vpp.jvpp.core.dto.GreTunnelDetailsReplyDump; import io.fd.vpp.jvpp.core.dto.GreTunnelDump; @@ -54,11 +55,15 @@ public class GreCustomizer extends FutureJVppCustomizer implements InitializingReaderCustomizer<Gre, GreBuilder>, InterfaceDataTranslator { private static final Logger LOG = LoggerFactory.getLogger(GreCustomizer.class); - private NamingContext interfaceContext; + private final NamingContext interfaceContext; + private final InterfaceCacheDumpManager dumpManager; - public GreCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { + public GreCustomizer(@Nonnull final FutureJVppCore jvpp, + @Nonnull final NamingContext interfaceContext, + @Nonnull final InterfaceCacheDumpManager dumpManager) { super(jvpp); this.interfaceContext = interfaceContext; + this.dumpManager = dumpManager; } @Override @@ -79,7 +84,7 @@ public class GreCustomizer extends FutureJVppCustomizer @Nonnull final ReadContext ctx) throws ReadFailedException { final InterfaceKey key = id.firstKeyOf(Interface.class); final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, GreTunnel.class, LOG)) { + if (!isInterfaceOfType(dumpManager, id, ctx, GreTunnel.class)) { return; } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterconnectionReadUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterconnectionReadUtils.java index 5c3072e42..a25531303 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterconnectionReadUtils.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterconnectionReadUtils.java @@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkState; import static java.util.Objects.requireNonNull; import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.vpp.jvpp.core.dto.BridgeDomainDetails; @@ -49,13 +50,16 @@ final class InterconnectionReadUtils implements InterfaceDataTranslator { private final FutureJVppCore futureJVppCore; private final NamingContext interfaceContext; private final NamingContext bridgeDomainContext; + private final InterfaceCacheDumpManager dumpManager; InterconnectionReadUtils(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext interfaceContext, - @Nonnull final NamingContext bridgeDomainContext) { + @Nonnull final NamingContext bridgeDomainContext, + @Nonnull final InterfaceCacheDumpManager dumpManager) { this.futureJVppCore = requireNonNull(futureJVppCore, "futureJVppCore should not be null"); this.interfaceContext = requireNonNull(interfaceContext, "interfaceContext should not be null"); this.bridgeDomainContext = requireNonNull(bridgeDomainContext, "bridgeDomainContext should not be null"); + this.dumpManager = requireNonNull(dumpManager, "dumpManager should not be null"); } @Nullable @@ -64,8 +68,7 @@ final class InterconnectionReadUtils implements InterfaceDataTranslator { throws ReadFailedException { final int ifaceId = interfaceContext.getIndex(ifaceName, ctx.getMappingContext()); - final SwInterfaceDetails iface = getVppInterfaceDetails(futureJVppCore, id, ifaceName, - ifaceId, ctx.getModificationCache(), LOG); + final SwInterfaceDetails iface = dumpManager.getInterfaceDetail(id, ctx, ifaceName); LOG.debug("Interface details for interface: {}, details: {}", ifaceName, iface); final BridgeDomainDetailsReplyDump dumpReply = getDumpReply(id); @@ -78,7 +81,7 @@ final class InterconnectionReadUtils implements InterfaceDataTranslator { // Set BVI if the bridgeDomainDetails.bviSwIfIndex == current sw if index final Optional<BridgeDomainDetails> bridgeDomainForInterface = - getBridgeDomainForInterface(dumpReply, bd.bdId); + getBridgeDomainForInterface(dumpReply, bd.bdId); // Since we already found an interface assigned to a bridge domain, the details for BD must be present checkState(bridgeDomainForInterface.isPresent()); if (bridgeDomainForInterface.get().bviSwIfIndex == ifaceId) { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizer.java index fe04e5d80..5ec0082e4 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizer.java @@ -17,25 +17,17 @@ package io.fd.hc2vpp.v3po.interfacesstate; import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.hc2vpp.v3po.DisabledInterfacesManager; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.ModificationCache; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.Initialized; import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Set; -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.Interfaces; @@ -54,36 +46,21 @@ import org.slf4j.LoggerFactory; /** * Customizer for reading ietf-interfaces:interfaces-state/interface. */ -public class InterfaceCustomizer extends FutureJVppCustomizer +public class InterfaceCustomizer implements InitializingListReaderCustomizer<Interface, InterfaceKey, InterfaceBuilder>, ByteDataTranslator, InterfaceDataTranslator { - public static final String DUMPED_IFCS_CONTEXT_KEY = - InterfaceCustomizer.class.getName() + "dumpedInterfacesDuringGetAllIds"; private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class); private final NamingContext interfaceNamingContext; private final DisabledInterfacesManager interfaceDisableContext; + private final InterfaceCacheDumpManager dumpManager; - public InterfaceCustomizer(@Nonnull final FutureJVppCore jvpp, - @Nonnull final NamingContext interfaceNamingContext, - @Nonnull final DisabledInterfacesManager interfaceDisableContext) { - super(jvpp); + public InterfaceCustomizer(@Nonnull final NamingContext interfaceNamingContext, + @Nonnull final DisabledInterfacesManager interfaceDisableContext, + @Nonnull final InterfaceCacheDumpManager dumpManager) { this.interfaceNamingContext = interfaceNamingContext; this.interfaceDisableContext = interfaceDisableContext; - } - - public static void cacheInterfaceDump(final @Nonnull ReadContext context, final SwInterfaceDetailsReplyDump ifaces) { - context.getModificationCache().put(DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream() - .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails))); - } - - @Nonnull - @SuppressWarnings("unchecked") - public static Map<Integer, SwInterfaceDetails> getCachedInterfaceDump(@Nonnull final ModificationCache ctx) { - return ctx.get(DUMPED_IFCS_CONTEXT_KEY) == null - ? new HashMap<>() - // allow customizers to update the cache - : (Map<Integer, SwInterfaceDetails>) ctx.get(DUMPED_IFCS_CONTEXT_KEY); + this.dumpManager = dumpManager; } @Nonnull @@ -106,9 +83,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer return; } - // Pass cached details from getAllIds to getDetails to avoid additional dumps - final SwInterfaceDetails iface = getVppInterfaceDetails(getFutureJVpp(), id, ifaceName, - index, ctx.getModificationCache(), LOG); + final SwInterfaceDetails iface = dumpManager.getInterfaceDetail(id, ctx, ifaceName); LOG.debug("Interface details for interface: {}, details: {}", ifaceName, iface); if (!isRegularInterface(iface)) { @@ -140,44 +115,13 @@ public class InterfaceCustomizer extends FutureJVppCustomizer @Nonnull final ReadContext context) throws ReadFailedException { final List<InterfaceKey> interfacesKeys; LOG.trace("Dumping all interfaces to get all IDs"); - - final SwInterfaceDump request = new SwInterfaceDump(); - request.nameFilter = "".getBytes(); - request.nameFilterValid = 0; - - final CompletableFuture<SwInterfaceDetailsReplyDump> swInterfaceDetailsReplyDumpCompletableFuture = - getFutureJVpp().swInterfaceDump(request).toCompletableFuture(); - final SwInterfaceDetailsReplyDump ifaces = - getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, id); - - if (null == ifaces || null == ifaces.swInterfaceDetails) { - LOG.debug("No interfaces for :{} found in VPP", id); - return Collections.emptyList(); - } - - // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes - cacheInterfaceDump(context, ifaces); - final MappingContext mappingCtx = context.getMappingContext(); - final Set<Integer> interfacesIdxs = ifaces.swInterfaceDetails.stream() + final Set<Integer> interfacesIdxs = dumpManager.getInterfaces(id, context) .filter(elt -> elt != null) // Filter out disabled interfaces, dont read them // This also prevents child readers in being invoked such as vxlan (which relies on disabling interfaces) .filter(elt -> !interfaceDisableContext .isInterfaceDisabled(elt.swIfIndex, mappingCtx)) - .map((elt) -> { - // Store interface name from VPP in context if not yet present - if (!interfaceNamingContext.containsName(elt.swIfIndex, mappingCtx)) { - interfaceNamingContext.addName(elt.swIfIndex, toString(elt.interfaceName), - mappingCtx); - } - LOG.trace("Interface with name: {}, VPP name: {} and index: {} found in VPP", - interfaceNamingContext.getName(elt.swIfIndex, mappingCtx), - elt.interfaceName, - elt.swIfIndex); - - return elt; - }) // filter out sub-interfaces .filter(InterfaceDataTranslator.INSTANCE::isRegularInterface) .map(elt -> elt.swIfIndex) @@ -207,7 +151,8 @@ public class InterfaceCustomizer extends FutureJVppCustomizer @Override public Initialized<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> init( - @Nonnull final InstanceIdentifier<Interface> id, @Nonnull final Interface readValue, @Nonnull final ReadContext ctx) { + @Nonnull final InstanceIdentifier<Interface> id, @Nonnull final Interface readValue, + @Nonnull final ReadContext ctx) { return Initialized.create(getCfgId(id), new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder() .setName(readValue.getName()) diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslator.java index b3c3679cd..ec47ee2f2 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslator.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslator.java @@ -17,23 +17,17 @@ package io.fd.hc2vpp.v3po.interfacesstate; import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.honeycomb.translate.ModificationCache; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; +import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.util.RWUtils; import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; import java.math.BigInteger; -import java.util.Map; import java.util.Objects; -import java.util.concurrent.CompletionStage; import java.util.stream.Collector; -import java.util.stream.Collectors; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; @@ -46,7 +40,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.VxlanGpeTunnel; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.VxlanTunnel; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; public interface InterfaceDataTranslator extends ByteDataTranslator, JvppReplyConsumer { @@ -136,74 +129,6 @@ public interface InterfaceDataTranslator extends ByteDataTranslator, JvppReplyCo return yangIfIndex - 1; } - - /** - * Queries VPP for interface description given interface key. - * - * @param futureJVppCore VPP Java Future API - * @param id InstanceIdentifier, which is passed in ReadFailedException - * @param name interface name - * @param index VPP index of the interface - * @param ctx per-tx scope context containing cached dump with all the interfaces. If the cache is not - * available or outdated, another dump will be performed. - * @return SwInterfaceDetails DTO or null if interface was not found - * @throws IllegalArgumentException If interface cannot be found - * @throws ReadFailedException If read operation had failed - */ - @Nonnull - default SwInterfaceDetails getVppInterfaceDetails(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final InstanceIdentifier<?> id, - @Nonnull final String name, final int index, - @Nonnull final ModificationCache ctx, - @Nonnull final Logger callerLogger) - throws ReadFailedException { - requireNonNull(futureJVppCore, "futureJVppCore should not be null"); - requireNonNull(name, "name should not be null"); - requireNonNull(ctx, "ctx should not be null"); - - final SwInterfaceDump request = new SwInterfaceDump(); - request.nameFilter = name.getBytes(); - request.nameFilterValid = 1; - - final Map<Integer, SwInterfaceDetails> allInterfaces = InterfaceCustomizer.getCachedInterfaceDump(ctx); - - // Returned cached if available - if (allInterfaces.containsKey(index)) { - return allInterfaces.get(index); - } - - SwInterfaceDetailsReplyDump ifaces; - - CompletionStage<SwInterfaceDetailsReplyDump> requestFuture = futureJVppCore.swInterfaceDump(request); - ifaces = getReplyForRead(requestFuture.toCompletableFuture(), id); - if (null == ifaces || null == ifaces.swInterfaceDetails || ifaces.swInterfaceDetails.isEmpty()) { - request.nameFilterValid = 0; - - callerLogger.warn("VPP returned null instead of interface by key {} and its not cached", name); - callerLogger.warn("Iterating through all the interfaces to find interface: {}", name); - - // Or else just perform full dump and do inefficient filtering - requestFuture = futureJVppCore.swInterfaceDump(request); - ifaces = getReplyForRead(requestFuture.toCompletableFuture(), id); - - // Update the cache - allInterfaces.clear(); - allInterfaces - .putAll(ifaces.swInterfaceDetails.stream().collect(Collectors.toMap(d -> d.swIfIndex, d -> d))); - - if (allInterfaces.containsKey(index)) { - return allInterfaces.get(index); - } - throw new IllegalArgumentException("Unable to find interface " + name); - } - - // SwInterfaceDump's name filter does prefix match, so we need additional filtering: - final SwInterfaceDetails iface = - ifaces.swInterfaceDetails.stream().filter(d -> d.swIfIndex == index).collect(SINGLE_ITEM_COLLECTOR); - allInterfaces.put(index, iface); // update the cache - return iface; - } - /** * Determine interface type based on its VPP name (relying on VPP's interface naming conventions) * @@ -240,20 +165,15 @@ public interface InterfaceDataTranslator extends ByteDataTranslator, JvppReplyCo } /** - * Check interface type. Uses interface details from VPP to determine. Uses {@link - * #getVppInterfaceDetails(FutureJVppCore, InstanceIdentifier, String, int, ModificationCache, Logger)} internally - * so tries to utilize cache before asking VPP. + * Check interface type. Uses interface details from VPP to determine. */ - default boolean isInterfaceOfType(@Nonnull final FutureJVppCore jvpp, - @Nonnull final ModificationCache cache, + default boolean isInterfaceOfType(@Nonnull final InterfaceCacheDumpManager dumpManager, @Nonnull final InstanceIdentifier<?> id, - final int index, - @Nonnull final Class<? extends InterfaceType> ifcType, - @Nonnull final Logger callerLogger) + @Nonnull final ReadContext ctx, + @Nonnull final Class<? extends InterfaceType> ifcType) throws ReadFailedException { final String name = id.firstKeyOf(Interface.class).getName(); - final SwInterfaceDetails vppInterfaceDetails = - getVppInterfaceDetails(jvpp, id, name, index, cache, callerLogger); + final SwInterfaceDetails vppInterfaceDetails = dumpManager.getInterfaceDetail(id, ctx, name); return isInterfaceOfType(ifcType, vppInterfaceDetails); } @@ -264,13 +184,11 @@ public interface InterfaceDataTranslator extends ByteDataTranslator, JvppReplyCo } /** - * Checks whether provided {@link SwInterfaceDetails} is detail of sub-interface<br> - * <li>subId == unique number of sub-interface within set of sub-interfaces of single interface - * <li>swIfIndex == unique index of interface/sub-interface within all interfaces - * <li>supSwIfIndex == unique index of parent interface - * <li>in case of interface , swIfIndex value equals supSwIfIndex - * <li>in case of subinterface, supSwIfIndex equals index of parent interface, - * swIfIndex is index of subinterface itselt + * Checks whether provided {@link SwInterfaceDetails} is detail of sub-interface<br> <li>subId == unique number of + * sub-interface within set of sub-interfaces of single interface <li>swIfIndex == unique index of + * interface/sub-interface within all interfaces <li>supSwIfIndex == unique index of parent interface <li>in case of + * interface , swIfIndex value equals supSwIfIndex <li>in case of subinterface, supSwIfIndex equals index of parent + * interface, swIfIndex is index of subinterface itselt */ default boolean isSubInterface(@Nonnull final SwInterfaceDetails elt) { //cant check by subId != 0, because you can pick 0 as value @@ -278,13 +196,11 @@ public interface InterfaceDataTranslator extends ByteDataTranslator, JvppReplyCo } /** - * Checks whether provided {@link SwInterfaceDetails} is detail of interface<br> - * <li>subId == unique number of subinterface within set of subinterfaces of single interface - * <li>swIfIndex == unique index of interface/subinterface within all interfaces - * <li>supSwIfIndex == unique index of parent interface - * <li>in case of interface , swIfIndex value equals supSwIfIndex - * <li>in case of subinterface, supSwIfIndex equals index of parent interface, - * swIfIndex is index of subinterface itselt + * Checks whether provided {@link SwInterfaceDetails} is detail of interface<br> <li>subId == unique number of + * subinterface within set of subinterfaces of single interface <li>swIfIndex == unique index of + * interface/subinterface within all interfaces <li>supSwIfIndex == unique index of parent interface <li>in case of + * interface , swIfIndex value equals supSwIfIndex <li>in case of subinterface, supSwIfIndex equals index of parent + * interface, swIfIndex is index of subinterface itselt */ default boolean isRegularInterface(@Nonnull final SwInterfaceDetails elt) { return !isSubInterface(elt); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/L2Customizer.java index c199dfd9e..1761b385f 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/L2Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/L2Customizer.java @@ -16,13 +16,14 @@ package io.fd.hc2vpp.v3po.interfacesstate; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.Initialized; import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.vpp.jvpp.core.future.FutureJVppCore; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; @@ -31,11 +32,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.VppInterfaceStateAugmentationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces.state._interface.L2; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces.state._interface.L2Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.config.attributes.interconnection.BridgeBasedBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.config.attributes.interconnection.XconnectBasedBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.state.attributes.Interconnection; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.state.attributes.interconnection.BridgeBased; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.config.attributes.interconnection.BridgeBasedBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.state.attributes.interconnection.XconnectBased; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.config.attributes.interconnection.XconnectBasedBuilder; import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -52,9 +53,11 @@ public class L2Customizer extends FutureJVppCustomizer implements InitializingRe public L2Customizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext interfaceContext, - @Nonnull final NamingContext bridgeDomainContext) { + @Nonnull final NamingContext bridgeDomainContext, + @Nonnull final InterfaceCacheDumpManager dumpManager) { super(futureJVppCore); - this.icReadUtils = new InterconnectionReadUtils(futureJVppCore, interfaceContext, bridgeDomainContext); + this.icReadUtils = + new InterconnectionReadUtils(futureJVppCore, interfaceContext, bridgeDomainContext, dumpManager); } @Override diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizer.java index 7dec4c265..46d85cfa1 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizer.java @@ -16,18 +16,16 @@ package io.fd.hc2vpp.v3po.interfacesstate; +import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; -import com.google.common.base.Preconditions; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.hc2vpp.common.translate.util.TagRewriteOperation; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; import java.util.ArrayList; import java.util.List; import javax.annotation.Nonnull; @@ -40,9 +38,9 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces. import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607._802dot1ad; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607._802dot1q; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.interfaces.state._interface.sub.interfaces.SubInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.sub._interface.l2.state.attributes.L2Builder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.rewrite.attributes.Rewrite; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.rewrite.attributes.RewriteBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.sub._interface.l2.state.attributes.L2Builder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.tag.rewrite.PushTags; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.tag.rewrite.PushTagsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.tag.rewrite.PushTagsKey; @@ -55,19 +53,17 @@ import org.slf4j.LoggerFactory; /** * Customizer for reading vlan tag-rewrite configuration state form the VPP. */ -public class RewriteCustomizer extends FutureJVppCustomizer +public class RewriteCustomizer implements ReaderCustomizer<Rewrite, RewriteBuilder>, InterfaceDataTranslator { // No initialization necessary since its parent Subinterface L2 customzier sets the entire subtree during // initialization private static final Logger LOG = LoggerFactory.getLogger(RewriteCustomizer.class); - private final NamingContext interfaceContext; + private final InterfaceCacheDumpManager dumpManager; - public RewriteCustomizer(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext interfaceContext) { - super(futureJVppCore); - this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); + public RewriteCustomizer(@Nonnull final InterfaceCacheDumpManager dumpManager) { + this.dumpManager = checkNotNull(dumpManager, "dumpManager should not be null"); } @Override @@ -89,8 +85,7 @@ public class RewriteCustomizer extends FutureJVppCustomizer final String subInterfaceName = getSubInterfaceName(id); LOG.debug("Reading attributes for sub interface: {}", subInterfaceName); - final SwInterfaceDetails iface = getVppInterfaceDetails(getFutureJVpp(), id, subInterfaceName, - interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()), ctx.getModificationCache(), LOG); + final SwInterfaceDetails iface = dumpManager.getInterfaceDetail(id, ctx, subInterfaceName); LOG.debug("VPP sub-interface details: {}", iface); checkState(isSubInterface(iface), "Interface returned by the VPP is not a sub-interface"); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceCustomizer.java index 2bf635fb9..9c39722ab 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceCustomizer.java @@ -16,12 +16,13 @@ package io.fd.hc2vpp.v3po.interfacesstate; +import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; -import com.google.common.base.Preconditions; import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; @@ -29,13 +30,10 @@ import io.fd.honeycomb.translate.spi.read.Initialized; import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; import io.fd.honeycomb.translate.util.RWUtils; import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.SwInterfaceDump; import io.fd.vpp.jvpp.core.future.FutureJVppCore; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.concurrent.CompletableFuture; +import java.util.Objects; import java.util.stream.Collectors; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.CVlan; @@ -74,17 +72,21 @@ import org.slf4j.LoggerFactory; * Customizer for reading sub interfaces form the VPP. */ public class SubInterfaceCustomizer extends FutureJVppCustomizer - implements InitializingListReaderCustomizer<SubInterface, SubInterfaceKey, SubInterfaceBuilder>, ByteDataTranslator, + implements InitializingListReaderCustomizer<SubInterface, SubInterfaceKey, SubInterfaceBuilder>, + ByteDataTranslator, InterfaceDataTranslator { private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceCustomizer.class); private static final Dot1qTag.VlanId ANY_VLAN_ID = new Dot1qTag.VlanId(Dot1qTag.VlanId.Enumeration.Any); - private NamingContext interfaceContext; + private final NamingContext interfaceContext; + private final InterfaceCacheDumpManager dumpManager; public SubInterfaceCustomizer(@Nonnull final FutureJVppCore jvpp, - @Nonnull final NamingContext interfaceContext) { + @Nonnull final NamingContext interfaceContext, + @Nonnull final InterfaceCacheDumpManager dumpManager) { super(jvpp); - this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.dumpManager = checkNotNull(dumpManager, "dumpManager should not be null"); } private static String getSubInterfaceName(final InstanceIdentifier<SubInterface> id) { @@ -119,30 +121,8 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer final String ifaceName = key.getName(); final int ifaceId = interfaceContext.getIndex(ifaceName, context.getMappingContext()); - // TODO HONEYCOMB-189 if we know that full dump was already performed we could use cache - // (checking if getCachedInterfaceDump() returns non empty map is not enough, because - // we could be part of particular iface state read - final SwInterfaceDump request = new SwInterfaceDump(); - request.nameFilter = "".getBytes(); - request.nameFilterValid = 0; - - final CompletableFuture<SwInterfaceDetailsReplyDump> swInterfaceDetailsReplyDumpCompletableFuture = - getFutureJVpp().swInterfaceDump(request).toCompletableFuture(); - final SwInterfaceDetailsReplyDump ifaces = - getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, id); - - if (null == ifaces || null == ifaces.swInterfaceDetails) { - LOG.warn("Looking for sub-interfaces, but no interfaces found in VPP"); - return Collections.emptyList(); - } - - // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes - context.getModificationCache() - .put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream() - .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails))); - - final List<SubInterfaceKey> interfacesKeys = ifaces.swInterfaceDetails.stream() - .filter(elt -> elt != null) + final List<SubInterfaceKey> interfacesKeys = dumpManager.getInterfaces(id,context) + .filter(Objects::nonNull) // accept only sub-interfaces for current iface: .filter(elt -> isSubInterface(elt) && elt.supSwIfIndex == ifaceId) .map(details -> new SubInterfaceKey(new Long(details.subId))) @@ -171,8 +151,7 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer final String subInterfaceName = getSubInterfaceName(id); LOG.debug("Reading attributes for sub interface: {}", subInterfaceName); - final SwInterfaceDetails iface = getVppInterfaceDetails(getFutureJVpp(), id, subInterfaceName, - interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()), ctx.getModificationCache(), LOG); + final SwInterfaceDetails iface = dumpManager.getInterfaceDetail(id, ctx, subInterfaceName); LOG.debug("VPP sub-interface details: {}", iface); checkState(isSubInterface(iface), "Interface returned by the VPP is not a sub-interface"); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2Customizer.java index f068ac26f..4fd200bd4 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2Customizer.java @@ -18,20 +18,17 @@ package io.fd.hc2vpp.v3po.interfacesstate; import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getSubInterfaceName; -import com.google.common.collect.ImmutableMap; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.Initialized; import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; import io.fd.honeycomb.translate.util.RWUtils; import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Map; import javax.annotation.Nonnull; 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.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.state.attributes.Interconnection; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.state.attributes.interconnection.BridgeBased; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.state.attributes.interconnection.XconnectBased; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.interfaces.state._interface.sub.interfaces.SubInterface; @@ -48,7 +45,7 @@ import org.slf4j.LoggerFactory; /** * Customizer for reading vlan sub interface L2 operational state */ -public class SubInterfaceL2Customizer extends FutureJVppCustomizer +public class SubInterfaceL2Customizer implements InitializingReaderCustomizer<L2, L2Builder> { private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceL2Customizer.class); @@ -56,9 +53,10 @@ public class SubInterfaceL2Customizer extends FutureJVppCustomizer public SubInterfaceL2Customizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext interfaceContext, - @Nonnull final NamingContext bridgeDomainContext) { - super(futureJVppCore); - this.icReadUtils = new InterconnectionReadUtils(futureJVppCore, interfaceContext, bridgeDomainContext); + @Nonnull final NamingContext bridgeDomainContext, + @Nonnull final InterfaceCacheDumpManager dumpManager) { + this.icReadUtils = + new InterconnectionReadUtils(futureJVppCore, interfaceContext, bridgeDomainContext, dumpManager); } @Override @@ -78,7 +76,8 @@ public class SubInterfaceL2Customizer extends FutureJVppCustomizer LOG.debug("Reading attributes for sub-interface L2: {}", id); final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class); final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); - final String subInterfaceName = getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); + final String subInterfaceName = + getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); builder.setInterconnection(icReadUtils.readInterconnection(id, subInterfaceName, ctx)); } @@ -89,27 +88,31 @@ public class SubInterfaceL2Customizer extends FutureJVppCustomizer @Nonnull final L2 readValue, @Nonnull final ReadContext ctx) { - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.sub._interface.l2.config.attributes.L2Builder builder= + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.sub._interface.l2.config.attributes.L2Builder + builder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.sub._interface.l2.config.attributes.L2Builder(); - if(readValue.getInterconnection() instanceof XconnectBased){ + if (readValue.getInterconnection() instanceof XconnectBased) { XconnectBased state = (XconnectBased) readValue.getInterconnection(); - builder.setInterconnection(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.config.attributes.interconnection.XconnectBasedBuilder() - .setXconnectOutgoingInterface(state.getXconnectOutgoingInterface()) - .build()); - }else { + builder.setInterconnection( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.config.attributes.interconnection.XconnectBasedBuilder() + .setXconnectOutgoingInterface(state.getXconnectOutgoingInterface()) + .build()); + } else { BridgeBased state = (BridgeBased) readValue.getInterconnection(); - builder.setInterconnection(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.config.attributes.interconnection.BridgeBasedBuilder() - .setBridgeDomain(state.getBridgeDomain()) - .setBridgedVirtualInterface(state.isBridgedVirtualInterface()) - .setSplitHorizonGroup(state.getSplitHorizonGroup()) - .build()); + builder.setInterconnection( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.config.attributes.interconnection.BridgeBasedBuilder() + .setBridgeDomain(state.getBridgeDomain()) + .setBridgedVirtualInterface(state.isBridgedVirtualInterface()) + .setSplitHorizonGroup(state.getSplitHorizonGroup()) + .build()); } return Initialized.create(getCfgId(id), builder.setRewrite(readValue.getRewrite()).build()); } - static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.sub._interface.l2.config.attributes.L2> getCfgId(final InstanceIdentifier<L2> id) { + static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.sub._interface.l2.config.attributes.L2> getCfgId( + final InstanceIdentifier<L2> id) { return SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class)) .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170607.sub._interface.l2.config.attributes.L2.class); } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizer.java index b3c7f788b..fb8e6b55c 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizer.java @@ -16,9 +16,12 @@ package io.fd.hc2vpp.v3po.interfacesstate; +import static java.lang.String.format; + import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.Initialized; @@ -53,12 +56,17 @@ public class TapCustomizer extends FutureJVppCustomizer implements InitializingReaderCustomizer<Tap, TapBuilder>, InterfaceDataTranslator, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(TapCustomizer.class); + // TODO - HC2VPP-213 - used dump cache manager public static final String DUMPED_TAPS_CONTEXT_KEY = TapCustomizer.class.getName() + "dumpedTapsDuringGetAllIds"; private NamingContext interfaceContext; + private final InterfaceCacheDumpManager dumpManager; - public TapCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { + public TapCustomizer(@Nonnull final FutureJVppCore jvpp, + @Nonnull final NamingContext interfaceContext, + @Nonnull final InterfaceCacheDumpManager dumpManager) { super(jvpp); this.interfaceContext = interfaceContext; + this.dumpManager = dumpManager; } @Override @@ -79,8 +87,11 @@ public class TapCustomizer extends FutureJVppCustomizer final InterfaceKey key = id.firstKeyOf(Interface.class); final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.Tap.class, LOG)) { + final SwInterfaceDetails ifcDetails = dumpManager.getInterfaceDetail(id, ctx, key.getName()); + + if (!isInterfaceOfType( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.Tap.class, + ifcDetails)) { return; } @@ -115,9 +126,6 @@ public class TapCustomizer extends FutureJVppCustomizer builder.setTapName(toString(swInterfaceTapDetails.devName)); - final SwInterfaceDetails ifcDetails = getVppInterfaceDetails(getFutureJVpp(), id, key.getName(), - interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache(), LOG); - if (ifcDetails.tag[0] != 0) { // tag supplied builder.setTag(toString(ifcDetails.tag)); } @@ -129,15 +137,21 @@ public class TapCustomizer extends FutureJVppCustomizer @Nonnull final InstanceIdentifier<Tap> id, @Nonnull final Tap readValue, @Nonnull final ReadContext ctx) { // The MAC address & tag is set from interface details, those details are retrieved from cache final InterfaceKey key = id.firstKeyOf(Interface.class); - final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - final SwInterfaceDetails ifcDetails = - InterfaceCustomizer.getCachedInterfaceDump(ctx.getModificationCache()).get(index); + + final SwInterfaceDetails ifcDetails; + try { + ifcDetails = dumpManager.getInterfaceDetail(id, ctx, key.getName()); + } catch (ReadFailedException e) { + throw new IllegalStateException(format("Unable to read interface %s", key.getName()), e); + } return Initialized.create(getCfgId(id), new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.TapBuilder() .setMac(new PhysAddress(vppPhysAddrToYang(ifcDetails.l2Address))) .setTapName(readValue.getTapName()) - .setTag(ifcDetails.tag[0] == 0 ? null : toString(ifcDetails.tag)) + .setTag(ifcDetails.tag[0] == 0 + ? null + : toString(ifcDetails.tag)) // tapBuilder.setDeviceInstance(); .build()); } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizer.java index 282e1a537..4ce646d98 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizer.java @@ -16,14 +16,17 @@ package io.fd.hc2vpp.v3po.interfacesstate; +import static java.lang.String.format; + +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.Initialized; import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; import io.fd.vpp.jvpp.core.dto.SwInterfaceVhostUserDetails; import io.fd.vpp.jvpp.core.dto.SwInterfaceVhostUserDetailsReplyDump; @@ -51,16 +54,22 @@ import org.slf4j.LoggerFactory; public class VhostUserCustomizer extends FutureJVppCustomizer - implements InitializingReaderCustomizer<VhostUser, VhostUserBuilder>, InterfaceDataTranslator, JvppReplyConsumer { + implements InitializingReaderCustomizer<VhostUser, VhostUserBuilder>, InterfaceDataTranslator, + JvppReplyConsumer { + //TODO - HC2VPP-212 - use dump cache manager public static final String DUMPED_VHOST_USERS_CONTEXT_KEY = VhostUserCustomizer.class.getName() + "dumpedVhostUsersDuringGetAllIds"; private static final Logger LOG = LoggerFactory.getLogger(VhostUserCustomizer.class); private NamingContext interfaceContext; + private final InterfaceCacheDumpManager dumpManager; - public VhostUserCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { + public VhostUserCustomizer(@Nonnull final FutureJVppCore jvpp, + @Nonnull final NamingContext interfaceContext, + @Nonnull final InterfaceCacheDumpManager dumpManager) { super(jvpp); this.interfaceContext = interfaceContext; + this.dumpManager = dumpManager; } @Override @@ -81,9 +90,12 @@ public class VhostUserCustomizer extends FutureJVppCustomizer final InterfaceKey key = id.firstKeyOf(Interface.class); final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, + final SwInterfaceDetails ifcDetails = dumpManager.getInterfaceDetail(id, ctx, key.getName()); + + + if (!isInterfaceOfType( org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.VhostUser.class, - LOG)) { + ifcDetails)) { return; } @@ -121,9 +133,6 @@ public class VhostUserCustomizer extends FutureJVppCustomizer LOG.trace("Vhost user interface: {} attributes returned from VPP: {}", key.getName(), swInterfaceVhostUserDetails); - final SwInterfaceDetails ifcDetails = getVppInterfaceDetails(getFutureJVpp(), id, key.getName(), - interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache(), LOG); - builder.setRole(swInterfaceVhostUserDetails.isServer == 1 ? VhostUserRole.Server : VhostUserRole.Client); @@ -147,14 +156,19 @@ public class VhostUserCustomizer extends FutureJVppCustomizer @Nonnull final ReadContext ctx) { // The tag is set from interface details, those details are retrieved from cache final InterfaceKey key = id.firstKeyOf(Interface.class); - final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - final SwInterfaceDetails ifcDetails = - InterfaceCustomizer.getCachedInterfaceDump(ctx.getModificationCache()).get(index); + final SwInterfaceDetails ifcDetails; + try { + ifcDetails = dumpManager.getInterfaceDetail(id, ctx, key.getName()); + } catch (ReadFailedException e) { + throw new IllegalStateException(format("Unable to find VHost interface %s", key.getName()), e); + } return Initialized.create(getCfgId(id), new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.VhostUserBuilder() .setRole(readValue.getRole()) .setSocket(readValue.getSocket()) - .setTag(ifcDetails.tag[0] == 0 ? null : toString(ifcDetails.tag)) + .setTag(ifcDetails.tag[0] == 0 + ? null + : toString(ifcDetails.tag)) .build()); } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizer.java index b2e352052..c11d2398c 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizer.java @@ -18,13 +18,24 @@ package io.fd.hc2vpp.v3po.interfacesstate; import static com.google.common.base.Preconditions.checkState; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.vpp.jvpp.core.dto.VxlanTunnelDetails; +import io.fd.vpp.jvpp.core.dto.VxlanTunnelDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.VxlanTunnelDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; import java.util.concurrent.CompletionStage; - import javax.annotation.Nonnull; - import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; @@ -44,33 +55,23 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.Initialized; -import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; -import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.vpp.jvpp.core.dto.VxlanTunnelDetails; -import io.fd.vpp.jvpp.core.dto.VxlanTunnelDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.VxlanTunnelDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; - public class VxlanCustomizer extends FutureJVppCustomizer -implements InitializingReaderCustomizer<Vxlan, VxlanBuilder>, InterfaceDataTranslator, JvppReplyConsumer { + implements InitializingReaderCustomizer<Vxlan, VxlanBuilder>, InterfaceDataTranslator, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(VxlanCustomizer.class); private final NamingContext interfaceContext; + private final InterfaceCacheDumpManager dumpManager; - public VxlanCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { + public VxlanCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext, + @Nonnull final InterfaceCacheDumpManager dumpManager) { super(jvpp); this.interfaceContext = interfaceContext; + this.dumpManager = dumpManager; } @Override public void merge(@Nonnull Builder<? extends DataObject> parentBuilder, - @Nonnull Vxlan readValue) { + @Nonnull Vxlan readValue) { ((VppInterfaceStateAugmentationBuilder) parentBuilder).setVxlan(readValue); } @@ -82,12 +83,12 @@ implements InitializingReaderCustomizer<Vxlan, VxlanBuilder>, InterfaceDataTrans @Override public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Vxlan> id, - @Nonnull final VxlanBuilder builder, - @Nonnull final ReadContext ctx) throws ReadFailedException { + @Nonnull final VxlanBuilder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { final InterfaceKey key = id.firstKeyOf(Interface.class); final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, VxlanTunnel.class, LOG)) { + if (!isInterfaceOfType(dumpManager, id, ctx, VxlanTunnel.class)) { return; } @@ -135,15 +136,15 @@ implements InitializingReaderCustomizer<Vxlan, VxlanBuilder>, InterfaceDataTrans builder.setEncapVrfId((long) swInterfaceVxlanDetails.encapVrfId); builder.setVni(new VxlanVni((long) swInterfaceVxlanDetails.vni)); switch (swInterfaceVxlanDetails.decapNextIndex) { - case 1: - builder.setDecapNext(L2Input.class); - break; - case 2: - builder.setDecapNext(NshProxy.class); - break; - default: - LOG.trace("Unsupported decap next index for vxlan: {}", swInterfaceVxlanDetails.decapNextIndex); - return; + case 1: + builder.setDecapNext(L2Input.class); + break; + case 2: + builder.setDecapNext(NshProxy.class); + break; + default: + LOG.trace("Unsupported decap next index for vxlan: {}", swInterfaceVxlanDetails.decapNextIndex); + return; } LOG.debug("Vxlan tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder); } @@ -159,15 +160,16 @@ implements InitializingReaderCustomizer<Vxlan, VxlanBuilder>, InterfaceDataTrans @Override public Initialized<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.Vxlan> init( - @Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan readValue, @Nonnull final ReadContext ctx) { + @Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan readValue, + @Nonnull final ReadContext ctx) { return Initialized.create(getCfgId(id), new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.VxlanBuilder() - .setDst(readValue.getDst()) - .setSrc(readValue.getSrc()) - .setEncapVrfId(readValue.getEncapVrfId()) - .setVni(new VxlanVni(readValue.getVni())) - .setDecapNext(readValue.getDecapNext()) - .build()); + .setDst(readValue.getDst()) + .setSrc(readValue.getSrc()) + .setEncapVrfId(readValue.getEncapVrfId()) + .setVni(new VxlanVni(readValue.getVni())) + .setDecapNext(readValue.getDecapNext()) + .build()); } private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.Vxlan> getCfgId( diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizer.java index 9afbdc7d6..2e2f60c2e 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizer.java @@ -18,14 +18,15 @@ package io.fd.hc2vpp.v3po.interfacesstate; import static com.google.common.base.Preconditions.checkState; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManager; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.Initialized; import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDetails; import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDetailsReplyDump; import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDump; @@ -57,11 +58,15 @@ public class VxlanGpeCustomizer extends FutureJVppCustomizer implements InitializingReaderCustomizer<VxlanGpe, VxlanGpeBuilder>, InterfaceDataTranslator, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(VxlanGpeCustomizer.class); - private NamingContext interfaceContext; + private final NamingContext interfaceContext; + private final InterfaceCacheDumpManager dumpManager; - public VxlanGpeCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) { + public VxlanGpeCustomizer(@Nonnull final FutureJVppCore jvpp, + @Nonnull final NamingContext interfaceContext, + @Nonnull final InterfaceCacheDumpManager dumpManager) { super(jvpp); this.interfaceContext = interfaceContext; + this.dumpManager = dumpManager; } @Override @@ -83,7 +88,7 @@ public class VxlanGpeCustomizer extends FutureJVppCustomizer final InterfaceKey key = id.firstKeyOf(Interface.class); final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, VxlanGpeTunnel.class, LOG)) { + if (!isInterfaceOfType(dumpManager, id, ctx, VxlanGpeTunnel.class)) { return; } @@ -147,7 +152,8 @@ public class VxlanGpeCustomizer extends FutureJVppCustomizer @Override public Initialized<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.VxlanGpe> init( - @Nonnull final InstanceIdentifier<VxlanGpe> id, @Nonnull final VxlanGpe readValue, @Nonnull final ReadContext ctx) { + @Nonnull final InstanceIdentifier<VxlanGpe> id, @Nonnull final VxlanGpe readValue, + @Nonnull final ReadContext ctx) { return Initialized.create(getCfgId(id), new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.VxlanGpeBuilder() .setLocal(readValue.getLocal()) diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/InterfaceCacheDumpManager.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/InterfaceCacheDumpManager.java new file mode 100644 index 000000000..589d59024 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/InterfaceCacheDumpManager.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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. + */ + +package io.fd.hc2vpp.v3po.interfacesstate.cache; + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; +import java.util.stream.Stream; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Manager for dump data of interfaces. The main purpose of this manager is to cache common interface data between + * various classes that process this kind of data. If reader does not use this utility, it introduces a big overhead + * because of size/complexity of interfaces dump + */ +public interface InterfaceCacheDumpManager { + + /** + * Provides stream of all currently configured vpp interfaces + * + * @param identifier id of currently processed data + * @param ctx context of current transaction + * @return {@link Stream} of currently configured interfaces + * @throws ReadFailedException if dumping of data was unsuccessful + */ + @Nonnull + Stream<SwInterfaceDetails> getInterfaces(@Nonnull final InstanceIdentifier<?> identifier, + @Nonnull final ReadContext ctx) throws ReadFailedException; + + /** + * Provides details of interface + * + * @param identifier id of currently processed data + * @param ctx context of current transaction + * @param interfaceName name of requested interface + * @return {@link SwInterfaceDetails} of requested interface + * @throws ReadFailedException if dumping of data was unsuccessful + */ + @Nullable + SwInterfaceDetails getInterfaceDetail(@Nonnull final InstanceIdentifier<?> identifier, + @Nonnull final ReadContext ctx, + @Nonnull final String interfaceName) throws ReadFailedException; +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/InterfaceCacheDumpManagerImpl.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/InterfaceCacheDumpManagerImpl.java new file mode 100644 index 000000000..e9b114018 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/InterfaceCacheDumpManagerImpl.java @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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. + */ + +package io.fd.hc2vpp.v3po.interfacesstate.cache; + +import static io.fd.hc2vpp.common.translate.util.JvppReplyConsumer.INSTANCE; +import static io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor.NO_PARAMS; +import static java.util.stream.Collectors.toMap; + +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.ModificationCache; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Stream; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Manager for dump data of interfaces/sub-interfaces + */ +final class InterfaceCacheDumpManagerImpl implements InterfaceCacheDumpManager { + + private static final Logger LOG = LoggerFactory.getLogger(InterfaceCacheDumpManagerImpl.class); + + // byNameIndex must be cached, not held as reference here, to have it destroyed with cache after transaction + static final String BY_NAME_INDEX_KEY = InterfaceCacheDumpManagerImpl.class.getName() + "_byNameIndex"; + private NamingContext namingContext; + private final DumpCacheManager<SwInterfaceDetailsReplyDump, String> specificDumpManager; + private final DumpCacheManager<SwInterfaceDetailsReplyDump, Void> fullDumpManager; + + InterfaceCacheDumpManagerImpl(@Nonnull final FutureJVppCore jvpp, + @Nonnull final NamingContext namingContext) { + this.namingContext = namingContext; + specificDumpManager = specificInterfaceDumpManager(jvpp); + fullDumpManager = fullInterfaceDumpManager(jvpp, + new StaticCacheKeyFactory(StaticCacheKeyFactory.class.getName() + "_dump")); + } + + @Override + @Nonnull + public synchronized Stream<SwInterfaceDetails> getInterfaces(@Nonnull final InstanceIdentifier<?> identifier, + @Nonnull final ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading all interfaces[{}]", identifier); + return initMapAndGet(identifier, ctx).entrySet().stream().map(Map.Entry::getValue); + } + + @Override + @Nullable + public synchronized SwInterfaceDetails getInterfaceDetail(@Nonnull final InstanceIdentifier<?> identifier, + @Nonnull final ReadContext ctx, + @Nonnull final String interfaceName) + throws ReadFailedException { + final Map<String, SwInterfaceDetails> interfaceIndex = getMap(ctx); + + // does not attempt to cover cases with concurrent updates, as tx should be atomic + if (interfaceIndex != null) { + // tries to find interface in map + return interfaceIndex.get(interfaceName); + } else { + // if map is not present, use specific dump(it will be cached standard way, under key constructed from IID) + return dumpSpecificDetail(identifier, ctx, interfaceName); + } + } + + private SwInterfaceDetails dumpSpecificDetail(@Nonnull final InstanceIdentifier<?> identifier, + @Nonnull final ReadContext ctx, + @Nonnull final String interfaceName) + throws ReadFailedException { + LOG.debug("Interface {} not present in cached data, performing specific dump[{}]", interfaceName, + identifier); + final SwInterfaceDetailsReplyDump reply = + specificDumpManager.getDump(identifier, ctx.getModificationCache(), interfaceName) + .or(new SwInterfaceDetailsReplyDump()); + + if (reply.swInterfaceDetails.isEmpty()) { + return null; + } + + return reply.swInterfaceDetails.get(0); + } + + private Map<String, SwInterfaceDetails> initMapAndGet(final InstanceIdentifier<?> identifier, final ReadContext ctx) + throws ReadFailedException { + + final ModificationCache cache = ctx.getModificationCache(); + if (!cache.containsKey(BY_NAME_INDEX_KEY)) { + LOG.debug("Performing dump[{}]", identifier); + final SwInterfaceDetailsReplyDump dump = + fullDumpManager.getDump(identifier, cache, NO_PARAMS) + .or(new SwInterfaceDetailsReplyDump()); + + // naming context initialization must be done here, as it is uses getName in next step, therefore it would + // create artificial mapping for every interface, because this happens before interface dump is processed + dump.swInterfaceDetails.forEach((elt) -> { + // Store interface name from VPP in context if not yet present + if (!namingContext.containsName(elt.swIfIndex, ctx.getMappingContext())) { + namingContext.addName(elt.swIfIndex, ByteDataTranslator.INSTANCE.toString(elt.interfaceName), + ctx.getMappingContext()); + } + LOG.trace("Interface with name: {}, VPP name: {} and index: {} found in VPP", + getInterfaceName(ctx, elt), + elt.interfaceName, + elt.swIfIndex); + }); + + final Map<String, SwInterfaceDetails> freshIndex = dump.swInterfaceDetails.stream() + .collect(toMap(detail -> getInterfaceName(ctx, detail), + detail -> detail)); + putMap(freshIndex, ctx); + } + + return getMap(ctx); + } + + private String getInterfaceName(final ReadContext ctx, final SwInterfaceDetails elt) { + return namingContext.getName(elt.swIfIndex, ctx.getMappingContext()); + } + + private static Map<String, SwInterfaceDetails> getMap(final ReadContext ctx) { + return (Map<String, SwInterfaceDetails>) ctx.getModificationCache().get(BY_NAME_INDEX_KEY); + } + + private static void putMap(final Map<String, SwInterfaceDetails> map, final ReadContext ctx) { + ctx.getModificationCache().put(BY_NAME_INDEX_KEY, map); + } + + + private static DumpCacheManager<SwInterfaceDetailsReplyDump, Void> fullInterfaceDumpManager( + final FutureJVppCore jvpp, + final StaticCacheKeyFactory cacheKeyFactory) { + return new DumpCacheManager.DumpCacheManagerBuilder<SwInterfaceDetailsReplyDump, Void>() + .withExecutor(fullInterfaceDumpExecutor(jvpp)) + .withCacheKeyFactory(cacheKeyFactory) + .acceptOnly(SwInterfaceDetailsReplyDump.class) + .build(); + } + + private static DumpCacheManager<SwInterfaceDetailsReplyDump, String> specificInterfaceDumpManager( + final FutureJVppCore jvpp) { + return new DumpCacheManager.DumpCacheManagerBuilder<SwInterfaceDetailsReplyDump, String>() + .withExecutor(specificInterfaceDumpExecutor(jvpp)) + .acceptOnly(SwInterfaceDetailsReplyDump.class) + .build(); + } + + private static EntityDumpExecutor<SwInterfaceDetailsReplyDump, Void> fullInterfaceDumpExecutor( + final FutureJVppCore api) { + return (identifier, params) -> { + final SwInterfaceDump request = new SwInterfaceDump(); + request.nameFilter = "".getBytes(); + request.nameFilterValid = 0; + + final CompletableFuture<SwInterfaceDetailsReplyDump> + swInterfaceDetailsReplyDumpCompletableFuture = api.swInterfaceDump(request).toCompletableFuture(); + return INSTANCE.getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, identifier); + }; + } + + private static EntityDumpExecutor<SwInterfaceDetailsReplyDump, String> specificInterfaceDumpExecutor( + final FutureJVppCore api) { + return (identifier, ifaceName) -> { + final SwInterfaceDump request = new SwInterfaceDump(); + request.nameFilter = ifaceName.getBytes(); + request.nameFilterValid = 1; + + final CompletableFuture<SwInterfaceDetailsReplyDump> + swInterfaceDetailsReplyDumpCompletableFuture = api.swInterfaceDump(request).toCompletableFuture(); + return INSTANCE.getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, identifier); + }; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/InterfaceCacheDumpManagerProvider.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/InterfaceCacheDumpManagerProvider.java new file mode 100644 index 000000000..7a6119bf1 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/InterfaceCacheDumpManagerProvider.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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. + */ + +package io.fd.hc2vpp.v3po.interfacesstate.cache; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.inject.Named; + +public class InterfaceCacheDumpManagerProvider implements Provider<InterfaceCacheDumpManager> { + + @Inject + private FutureJVppCore jvpp; + + @Inject + @Named("interface-context") + private NamingContext namingContext; + + @Override + public InterfaceCacheDumpManager get() { + return new InterfaceCacheDumpManagerImpl(jvpp, namingContext); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/StaticCacheKeyFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/StaticCacheKeyFactory.java new file mode 100644 index 000000000..e34e915e2 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/StaticCacheKeyFactory.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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. + */ + +package io.fd.hc2vpp.v3po.interfacesstate.cache; + +import io.fd.honeycomb.translate.util.read.cache.CacheKeyFactory; +import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class StaticCacheKeyFactory implements CacheKeyFactory<Void> { + + private final String key; + + public StaticCacheKeyFactory(@Nonnull final String key) { + this.key = key; + } + + @Nonnull + @Override + public String createKey(@Nonnull final InstanceIdentifier<?> actualContextIdentifier, + @Nullable final Void dumpParams) { + return key; + } + + @Nonnull + @Override + public Class<?> getCachedDataType() { + return SwInterfaceDetailsReplyDump.class; + } +} |