From ae37a3a44a56ccbbc760744f36ad9140aecc06eb Mon Sep 17 00:00:00 2001 From: Jan Srnicek Date: Fri, 7 Oct 2016 11:11:09 +0200 Subject: Pbb Support models/implementation refactored to work as rewrite on interfaces Change-Id: I8ce42905ce8f183c354e718d02291aea2435110d Signed-off-by: Jan Srnicek --- v3po/api/src/main/yang/pbb-types.yang | 81 ++++++ v3po/api/src/main/yang/vpp-pbb.yang | 32 +++ .../v3po/InterfacesStateReaderFactory.java | 47 +++- .../translate/v3po/InterfacesWriterFactory.java | 91 ++++--- .../v3po/interfaces/pbb/PbbRewriteCustomizer.java | 130 +++++++++ .../pbb/PbbRewriteStateCustomizer.java | 42 +++ .../interfaces/pbb/PbbRewriteCustomizerTest.java | 296 +++++++++++++++++++++ .../pbb/PbbRewriteStateCustomizerTest.java | 19 ++ 8 files changed, 685 insertions(+), 53 deletions(-) create mode 100644 v3po/api/src/main/yang/pbb-types.yang create mode 100644 v3po/api/src/main/yang/vpp-pbb.yang create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/pbb/PbbRewriteCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/pbb/PbbRewriteStateCustomizer.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/pbb/PbbRewriteCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/pbb/PbbRewriteStateCustomizerTest.java (limited to 'v3po') diff --git a/v3po/api/src/main/yang/pbb-types.yang b/v3po/api/src/main/yang/pbb-types.yang new file mode 100644 index 000000000..1b3d4b6d5 --- /dev/null +++ b/v3po/api/src/main/yang/pbb-types.yang @@ -0,0 +1,81 @@ +module pbb-types { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:pbb-types"; + prefix "pbb-types"; + + description "Common types used for defining Pbb based subinterfaces"; + + revision "2016-07-04" { + description + "Initial revision."; + } + + import ietf-yang-types { + prefix yang; + } + + import ietf-interfaces { + prefix if; + } + + import yang-ext { + prefix "ext"; + } + + typedef operation { + type enumeration { + // NOTE - Does not specify disabled enum value(0), because its used internally to delete/disable rewrite + enum "push-2"{ + value 2; + } + + enum "pop-2"{ + value 4; + description "Encapsulate/Decapsulate pbb packet according to incoming/outcoming direction"; + } + enum "translate-2-1"{ + value 7; + } + } + } + + grouping pbb-rewrite-attributes { + description "Provider Backbone Bridge attributes"; + + leaf destination-address{ + type yang:mac-address; + description "backbone destination address"; + } + + leaf source-address{ + type yang:mac-address; + description "backbone source address"; + } + + leaf outer-tag{ + type uint16; + } + + leaf b-vlan-tag-vlan-id{ + type uint16{ + //12 bit range + range "1..4095"; + } + description "backbone vlan id"; + } + + leaf i-tag-isid { + type uint32{ + //24 bit range + range "1..16777215"; + } + description "identifier of the backbone service instance "; + } + + leaf interface-operation { + type operation; + default pop-2; + description "Define operation that will pbb interface perform while processing packets"; + } + } +} diff --git a/v3po/api/src/main/yang/vpp-pbb.yang b/v3po/api/src/main/yang/vpp-pbb.yang new file mode 100644 index 000000000..848f04e6c --- /dev/null +++ b/v3po/api/src/main/yang/vpp-pbb.yang @@ -0,0 +1,32 @@ +module vpp-pbb { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:vpp-pbb"; + prefix "vpp-pbb"; + + revision "2016-04-10" { + description "Initial revision of pbb model"; + } + + import pbb-types{ + prefix "pbb-types"; + } + + import yang-ext { + prefix "ext"; + } + + augment /if:interfaces/if:interface { + ext:augment-identifier "pbb-rewrite-interface-augmentation"; + container pbb-rewrite{ + uses pbb-types:pbb-rewrite-attributes; + } + } + + augment /if:interfaces-state/if:interface { + ext:augment-identifier "pbb-rewrite-state-interface-augmentation"; + container pbb-rewrite-state{ + uses pbb-types:pbb-rewrite-attributes; + config false; + } + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesStateReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesStateReaderFactory.java index 0a94a1bed..c7f80e329 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesStateReaderFactory.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesStateReaderFactory.java @@ -25,7 +25,6 @@ import io.fd.honeycomb.translate.read.ReaderFactory; import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; import io.fd.honeycomb.translate.v3po.interfacesstate.EthernetCustomizer; import io.fd.honeycomb.translate.v3po.interfacesstate.GreCustomizer; -import io.fd.honeycomb.translate.v3po.interfacesstate.acl.ingress.AclCustomizer; import io.fd.honeycomb.translate.v3po.interfacesstate.InterfaceCustomizer; import io.fd.honeycomb.translate.v3po.interfacesstate.L2Customizer; import io.fd.honeycomb.translate.v3po.interfacesstate.ProxyArpCustomizer; @@ -33,10 +32,12 @@ import io.fd.honeycomb.translate.v3po.interfacesstate.TapCustomizer; import io.fd.honeycomb.translate.v3po.interfacesstate.VhostUserCustomizer; import io.fd.honeycomb.translate.v3po.interfacesstate.VxlanCustomizer; import io.fd.honeycomb.translate.v3po.interfacesstate.VxlanGpeCustomizer; +import io.fd.honeycomb.translate.v3po.interfacesstate.acl.ingress.AclCustomizer; import io.fd.honeycomb.translate.v3po.interfacesstate.ip.Ipv4AddressCustomizer; import io.fd.honeycomb.translate.v3po.interfacesstate.ip.Ipv4Customizer; import io.fd.honeycomb.translate.v3po.interfacesstate.ip.Ipv4NeighbourCustomizer; import io.fd.honeycomb.translate.v3po.interfacesstate.ip.Ipv6Customizer; +import io.fd.honeycomb.translate.v3po.interfacesstate.pbb.PbbRewriteStateCustomizer; import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; import io.fd.honeycomb.translate.vpp.util.NamingContext; import io.fd.vpp.jvpp.core.future.FutureJVppCore; @@ -65,6 +66,9 @@ 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.rev150105.interfaces.state._interface.Vxlan; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.VxlanGpe; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev160410.PbbRewriteStateInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev160410.PbbRewriteStateInterfaceAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev160410.interfaces.state._interface.PbbRewriteState; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public final class InterfacesStateReaderFactory implements ReaderFactory { @@ -76,7 +80,7 @@ public final class InterfacesStateReaderFactory implements ReaderFactory { private final FutureJVppCore jvpp; static final InstanceIdentifier IFC_STATE_ID = - InstanceIdentifier.create(InterfacesState.class); + InstanceIdentifier.create(InterfacesState.class); static final InstanceIdentifier IFC_ID = IFC_STATE_ID.child(Interface.class); @Inject @@ -105,6 +109,8 @@ public final class InterfacesStateReaderFactory implements ReaderFactory { initInterface2AugmentationReaders(registry, IFC_ID); // vpp-vlan.yang new SubinterfaceStateAugmentationReaderFactory(jvpp, ifcNamingCtx, bdNamingCtx, classifyContext).init(registry); + //vpp-pbb.yang + initPbbRewriteAugmentation(registry, IFC_ID); } private void initInterface2AugmentationReaders(final ModifiableReaderRegistryBuilder registry, @@ -130,39 +136,54 @@ public final class InterfacesStateReaderFactory implements ReaderFactory { final InstanceIdentifier ifcId) { // VppInterfaceStateAugmentation final InstanceIdentifier vppIfcAugId = - ifcId.augmentation(VppInterfaceStateAugmentation.class); + ifcId.augmentation(VppInterfaceStateAugmentation.class); registry.addStructuralReader(vppIfcAugId, VppInterfaceStateAugmentationBuilder.class); // Ethernet registry - .add(new GenericReader<>(vppIfcAugId.child(Ethernet.class), new EthernetCustomizer(jvpp, ifcNamingCtx))); + .add(new GenericReader<>(vppIfcAugId.child(Ethernet.class), + new EthernetCustomizer(jvpp, ifcNamingCtx))); // Tap registry.add(new GenericReader<>(vppIfcAugId.child(Tap.class), new TapCustomizer(jvpp, ifcNamingCtx))); // VhostUser registry - .add(new GenericReader<>(vppIfcAugId.child(VhostUser.class), new VhostUserCustomizer(jvpp, ifcNamingCtx))); + .add(new GenericReader<>(vppIfcAugId.child(VhostUser.class), + new VhostUserCustomizer(jvpp, ifcNamingCtx))); // Vxlan registry.add(new GenericReader<>(vppIfcAugId.child(Vxlan.class), new VxlanCustomizer(jvpp, ifcNamingCtx))); // VxlanGpe registry - .add(new GenericReader<>(vppIfcAugId.child(VxlanGpe.class), new VxlanGpeCustomizer(jvpp, ifcNamingCtx))); + .add(new GenericReader<>(vppIfcAugId.child(VxlanGpe.class), + new VxlanGpeCustomizer(jvpp, ifcNamingCtx))); // Gre registry.add(new GenericReader<>(vppIfcAugId.child(Gre.class), new GreCustomizer(jvpp, ifcNamingCtx))); // L2 registry - .add(new GenericReader<>(vppIfcAugId.child(L2.class), new L2Customizer(jvpp, ifcNamingCtx, bdNamingCtx))); + .add(new GenericReader<>(vppIfcAugId.child(L2.class), + new L2Customizer(jvpp, ifcNamingCtx, bdNamingCtx))); // Acl(Structural) final InstanceIdentifier aclIid = vppIfcAugId.child(Acl.class); registry.addStructuralReader(aclIid, AclBuilder.class); // Ingress(Subtree) final InstanceIdentifier ingressIdRelative = InstanceIdentifier.create(Ingress.class); registry.subtreeAdd( - Sets.newHashSet(ingressIdRelative.child(L2Acl.class), ingressIdRelative.child(Ip4Acl.class), - ingressIdRelative.child(Ip6Acl.class)), - new GenericReader<>(aclIid.child(Ingress.class), - new AclCustomizer(jvpp, ifcNamingCtx, - classifyContext))); + Sets.newHashSet(ingressIdRelative.child(L2Acl.class), ingressIdRelative.child(Ip4Acl.class), + ingressIdRelative.child(Ip6Acl.class)), + new GenericReader<>(aclIid.child(Ingress.class), + new AclCustomizer(jvpp, ifcNamingCtx, + classifyContext))); // Proxy ARP registry.add(new GenericReader<>(vppIfcAugId.child(ProxyArp.class), new ProxyArpCustomizer(jvpp, - ifcNamingCtx))); + ifcNamingCtx))); } + + private void initPbbRewriteAugmentation(final ModifiableReaderRegistryBuilder registry, + final InstanceIdentifier ifcId) { + + registry.addStructuralReader(ifcId.augmentation(PbbRewriteStateInterfaceAugmentation.class), + PbbRewriteStateInterfaceAugmentationBuilder.class); + + registry.add(new GenericReader<>(ifcId.augmentation(PbbRewriteStateInterfaceAugmentation.class).child( + PbbRewriteState.class), new PbbRewriteStateCustomizer(jvpp))); + } + } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesWriterFactory.java index 29a6ac5a4..d138dac62 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesWriterFactory.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesWriterFactory.java @@ -41,6 +41,7 @@ import io.fd.honeycomb.translate.v3po.interfaces.ip.Ipv4AddressCustomizer; import io.fd.honeycomb.translate.v3po.interfaces.ip.Ipv4Customizer; import io.fd.honeycomb.translate.v3po.interfaces.ip.Ipv4NeighbourCustomizer; import io.fd.honeycomb.translate.v3po.interfaces.ip.Ipv6Customizer; +import io.fd.honeycomb.translate.v3po.interfaces.pbb.PbbRewriteCustomizer; import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager; import io.fd.honeycomb.translate.vpp.util.NamingContext; import io.fd.honeycomb.translate.write.WriterFactory; @@ -71,24 +72,26 @@ 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.rev150105.interfaces._interface.Vxlan; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanGpe; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev160410.PbbRewriteInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev160410.interfaces._interface.PbbRewrite; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public final class InterfacesWriterFactory implements WriterFactory { public static final InstanceIdentifier IFC_ID = - InstanceIdentifier.create(Interfaces.class).child(Interface.class); + InstanceIdentifier.create(Interfaces.class).child(Interface.class); public static final InstanceIdentifier VPP_IFC_AUG_ID = - IFC_ID.augmentation(VppInterfaceAugmentation.class); + IFC_ID.augmentation(VppInterfaceAugmentation.class); public static final InstanceIdentifier ACL_ID = VPP_IFC_AUG_ID.child(Acl.class); public static final InstanceIdentifier INGRESS_ACL_ID = ACL_ID.child(Ingress.class); public static final InstanceIdentifier L2_ID = VPP_IFC_AUG_ID.child(L2.class); public static final InstanceIdentifier IETF_ACL_ID = VPP_IFC_AUG_ID.child(IetfAcl.class); public static final InstanceIdentifier - INGRESS_IETF_ACL_ID = IETF_ACL_ID.child( - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.ietf.acl.Ingress.class); + INGRESS_IETF_ACL_ID = IETF_ACL_ID.child( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.ietf.acl.Ingress.class); public static final InstanceIdentifier - EGRESS_IETF_ACL_ID = IETF_ACL_ID.child( - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.ietf.acl.Egress.class); + EGRESS_IETF_ACL_ID = IETF_ACL_ID.child( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.ietf.acl.Egress.class); private final FutureJVppCore jvpp; private final IetfAClWriter aclWriter; @@ -123,7 +126,9 @@ public final class InterfacesWriterFactory implements WriterFactory { addInterface1AugmentationWriters(IFC_ID, registry); // SubinterfaceAugmentation new SubinterfaceAugmentationWriterFactory(jvpp, aclWriter, ifcNamingContext, bdNamingContext, - classifyTableContext).init(registry); + classifyTableContext).init(registry); + + addPbbAugmentationWriters(IFC_ID, registry); } private void addInterface1AugmentationWriters(final InstanceIdentifier ifcId, @@ -131,19 +136,19 @@ public final class InterfacesWriterFactory implements WriterFactory { final InstanceIdentifier ifc1AugId = ifcId.augmentation(Interface1.class); // Ipv6(after interface) = registry.addAfter(new GenericWriter<>(ifc1AugId.child(Ipv6.class), new Ipv6Customizer(jvpp)), - ifcId); + ifcId); // Ipv4(after interface) final InstanceIdentifier ipv4Id = ifc1AugId.child(Ipv4.class); registry.addAfter(new GenericWriter<>(ipv4Id, new Ipv4Customizer(jvpp)), - ifcId); + ifcId); // Address(after Ipv4) = final InstanceIdentifier
ipv4AddressId = ipv4Id.child(Address.class); registry.addAfter(new GenericListWriter<>(ipv4AddressId, new Ipv4AddressCustomizer(jvpp, ifcNamingContext)), - ipv4Id); + ipv4Id); // Neighbor(after ipv4Address) registry.addAfter(new GenericListWriter<>(ipv4Id.child(Neighbor.class), new Ipv4NeighbourCustomizer(jvpp, - ifcNamingContext)), - ipv4AddressId); + ifcNamingContext)), + ipv4AddressId); } private void addVppInterfaceAgmentationWriters(final InstanceIdentifier ifcId, @@ -151,24 +156,24 @@ public final class InterfacesWriterFactory implements WriterFactory { // VhostUser(Needs to be executed before Interface customizer) = final InstanceIdentifier vhostId = VPP_IFC_AUG_ID.child(VhostUser.class); registry.addBefore(new GenericWriter<>(vhostId, new VhostUserCustomizer(jvpp, ifcNamingContext)), - ifcId); + ifcId); // Vxlan(Needs to be executed before Interface customizer) = final InstanceIdentifier vxlanId = VPP_IFC_AUG_ID.child(Vxlan.class); registry.addBefore(new GenericWriter<>(vxlanId, new VxlanCustomizer(jvpp, ifcNamingContext, ifcDisableContext)), - ifcId); + ifcId); // VxlanGpe(Needs to be executed before Interface customizer) = final InstanceIdentifier vxlanGpeId = VPP_IFC_AUG_ID.child(VxlanGpe.class); registry.addBefore(new GenericWriter<>(vxlanGpeId, - new VxlanGpeCustomizer(jvpp, ifcNamingContext, ifcDisableContext)), ifcId); + new VxlanGpeCustomizer(jvpp, ifcNamingContext, ifcDisableContext)), ifcId); // Tap(Needs to be executed before Interface customizer) = final InstanceIdentifier tapId = VPP_IFC_AUG_ID.child(Tap.class); registry.addBefore(new GenericWriter<>(tapId, new TapCustomizer(jvpp, ifcNamingContext)), - ifcId); + ifcId); // Gre(Needs to be executed before Interface customizer) = final InstanceIdentifier greId = VPP_IFC_AUG_ID.child(Gre.class); registry.addBefore(new GenericWriter<>(greId, new GreCustomizer(jvpp, ifcNamingContext)), - ifcId); + ifcId); final Set> specificIfcTypes = Sets.newHashSet(vhostId, vxlanGpeId, vxlanGpeId, tapId); @@ -177,48 +182,54 @@ public final class InterfacesWriterFactory implements WriterFactory { registry.add(new GenericWriter<>(VPP_IFC_AUG_ID.child(Ethernet.class), new EthernetCustomizer(jvpp))); // Routing(Execute only after specific interface customizers) = registry.addAfter( - new GenericWriter<>(VPP_IFC_AUG_ID.child(Routing.class), new RoutingCustomizer(jvpp, ifcNamingContext)), - specificIfcTypes); + new GenericWriter<>(VPP_IFC_AUG_ID.child(Routing.class), new RoutingCustomizer(jvpp, ifcNamingContext)), + specificIfcTypes); // L2(Execute only after subinterface (and all other ifc types) = registry.addAfter(new GenericWriter<>(L2_ID, new L2Customizer(jvpp, ifcNamingContext, bdNamingContext)), - SubinterfaceAugmentationWriterFactory.SUB_IFC_ID); + SubinterfaceAugmentationWriterFactory.SUB_IFC_ID); // Proxy Arp (execute after specific interface customizers) registry.addAfter( - new GenericWriter<>(VPP_IFC_AUG_ID.child(ProxyArp.class), new ProxyArpCustomizer(jvpp)), - specificIfcTypes); + new GenericWriter<>(VPP_IFC_AUG_ID.child(ProxyArp.class), new ProxyArpCustomizer(jvpp)), + specificIfcTypes); // Ingress (execute after classify table and session writers) // also handles L2Acl, Ip4Acl and Ip6Acl: final InstanceIdentifier ingressId = InstanceIdentifier.create(Ingress.class); registry - .subtreeAddAfter( - Sets.newHashSet(ingressId.child(L2Acl.class), ingressId.child(Ip4Acl.class), - ingressId.child(Ip6Acl.class)), - new GenericWriter<>(INGRESS_ACL_ID, - new AclCustomizer(jvpp, ifcNamingContext, classifyTableContext)), - Sets.newHashSet(CLASSIFY_TABLE_ID, CLASSIFY_SESSION_ID)); + .subtreeAddAfter( + Sets.newHashSet(ingressId.child(L2Acl.class), ingressId.child(Ip4Acl.class), + ingressId.child(Ip6Acl.class)), + new GenericWriter<>(INGRESS_ACL_ID, + new AclCustomizer(jvpp, ifcNamingContext, classifyTableContext)), + Sets.newHashSet(CLASSIFY_TABLE_ID, CLASSIFY_SESSION_ID)); // Ingress IETF-ACL, also handles AccessLists and Acl: final InstanceIdentifier accessListsIdIngress = InstanceIdentifier.create( - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.ietf.acl.Ingress.class) - .child(AccessLists.class); + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.ietf.acl.Ingress.class) + .child(AccessLists.class); final InstanceIdentifier aclIdIngress = accessListsIdIngress.child( - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.ietf.acl.base.attributes.access.lists.Acl.class); + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.ietf.acl.base.attributes.access.lists.Acl.class); registry.subtreeAdd( - Sets.newHashSet(accessListsIdIngress, aclIdIngress), - new GenericWriter<>(INGRESS_IETF_ACL_ID, new IetfAclCustomizer(aclWriter, ifcNamingContext))); + Sets.newHashSet(accessListsIdIngress, aclIdIngress), + new GenericWriter<>(INGRESS_IETF_ACL_ID, new IetfAclCustomizer(aclWriter, ifcNamingContext))); // Ingress IETF-ACL, also handles AccessLists and Acl: final InstanceIdentifier accessListsIdEgress = InstanceIdentifier.create( - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.ietf.acl.Egress.class) - .child(AccessLists.class); + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.ietf.acl.Egress.class) + .child(AccessLists.class); final InstanceIdentifier aclIdEgress = accessListsIdEgress.child( - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.ietf.acl.base.attributes.access.lists.Acl.class); + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.ietf.acl.base.attributes.access.lists.Acl.class); registry.subtreeAdd( - Sets.newHashSet(accessListsIdEgress, aclIdEgress), - new GenericWriter<>(EGRESS_IETF_ACL_ID, - new io.fd.honeycomb.translate.v3po.interfaces.acl.egress.IetfAclCustomizer(aclWriter, - ifcNamingContext))); + Sets.newHashSet(accessListsIdEgress, aclIdEgress), + new GenericWriter<>(EGRESS_IETF_ACL_ID, + new io.fd.honeycomb.translate.v3po.interfaces.acl.egress.IetfAclCustomizer(aclWriter, + ifcNamingContext))); } + private void addPbbAugmentationWriters(final InstanceIdentifier ifcId, + final ModifiableWriterRegistryBuilder registry) { + final InstanceIdentifier pbbRewriteId = + ifcId.augmentation(PbbRewriteInterfaceAugmentation.class).child(PbbRewrite.class); + registry.add(new GenericWriter<>(pbbRewriteId, new PbbRewriteCustomizer(jvpp, ifcNamingContext))); + } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/pbb/PbbRewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/pbb/PbbRewriteCustomizer.java new file mode 100644 index 000000000..79256ea58 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/pbb/PbbRewriteCustomizer.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2016 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.honeycomb.translate.v3po.interfaces.pbb; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.vpp.util.MacTranslator; +import io.fd.honeycomb.translate.vpp.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.L2InterfacePbbTagRewrite; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev160410.interfaces._interface.PbbRewrite; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class PbbRewriteCustomizer extends FutureJVppCustomizer + implements WriterCustomizer, MacTranslator, JvppReplyConsumer { + + private static final int OPERATION_DISABLE = 0; + + private final NamingContext interfaceNamingContext; + + public PbbRewriteCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceNamingContext) { + super(futureJVppCore); + this.interfaceNamingContext = checkNotNull(interfaceNamingContext, "Interface naming context cannot be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final PbbRewrite dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + try { + setPbbRewrite(id, dataAfter, writeContext, false); + } catch (TimeoutException | VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final PbbRewrite dataBefore, @Nonnull final PbbRewrite dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + try { + setPbbRewrite(id, dataAfter, writeContext, false); + } catch (TimeoutException | VppBaseCallException e) { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); + } + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final PbbRewrite dataBefore, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + try { + setPbbRewrite(id, dataBefore, writeContext, true); + } catch (TimeoutException | VppBaseCallException e) { + throw new WriteFailedException.DeleteFailedException(id, e); + } + } + + private void setPbbRewrite(final InstanceIdentifier id, final PbbRewrite data, + final WriteContext writeContext, final boolean disable) + throws TimeoutException, VppBaseCallException { + final String interfaceName = checkNotNull(id.firstKeyOf(Interface.class), "Interface key not found").getName(); + + final L2InterfacePbbTagRewrite request = new L2InterfacePbbTagRewrite(); + + //checking all attributes in preconditions(pbb-rewrite is subcontainer, so there can't be mandatory statements) + request.swIfIndex = interfaceNamingContext.getIndex(interfaceName, writeContext.getMappingContext()); + request.bDmac = parseMac(verifiedDestinationAddress(data)); + request.bSmac = parseMac(verifiedSourceAddress(data)); + request.bVlanid = verifiedBVlanId(data); + request.iSid = verifiedISid(data); + request.vtrOp = verifiedOperation(data, disable); + + //not sure whats gonna happen to this attribute, so its left optional for now + if (data.getOuterTag() != null) { + request.outerTag = data.getOuterTag().shortValue(); + } + + getReply(getFutureJVpp().l2InterfacePbbTagRewrite(request).toCompletableFuture()); + } + + private String verifiedDestinationAddress(final PbbRewrite data) { + return checkNotNull(data.getDestinationAddress(), "Destination address cannot be null").getValue(); + } + + private String verifiedSourceAddress(final PbbRewrite data) { + return checkNotNull(data.getSourceAddress(), "Destination address cannot be null").getValue(); + } + + private byte verifiedBVlanId(final PbbRewrite data) { + return (byte) checkNotNull(data.getBVlanTagVlanId(), "BVlan id cannot be null").shortValue(); + } + + private int verifiedISid(final PbbRewrite data) { + return checkNotNull(data.getITagIsid(), "ISid cannot be null").intValue(); + } + + // if disabled ,then uses non-public allowed value 0, which is equal to operation disable + private int verifiedOperation(final PbbRewrite data, final boolean disable) { + + return disable + ? OPERATION_DISABLE + : checkNotNull(data.getInterfaceOperation(), "Operation cannot be null").getIntValue(); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/pbb/PbbRewriteStateCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/pbb/PbbRewriteStateCustomizer.java new file mode 100644 index 000000000..718e3b16c --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/pbb/PbbRewriteStateCustomizer.java @@ -0,0 +1,42 @@ +package io.fd.honeycomb.translate.v3po.interfacesstate.pbb; + + +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.honeycomb.translate.vpp.util.FutureJVppCustomizer; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev160410.PbbRewriteStateInterfaceAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev160410.interfaces.state._interface.PbbRewriteState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev160410.interfaces.state._interface.PbbRewriteStateBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class PbbRewriteStateCustomizer extends FutureJVppCustomizer + implements ReaderCustomizer { + + public PbbRewriteStateCustomizer(@Nonnull final FutureJVppCore futureJVppCore) { + super(futureJVppCore); + } + + @Nonnull + @Override + public PbbRewriteStateBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new PbbRewriteStateBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final PbbRewriteStateBuilder builder, @Nonnull final ReadContext ctx) + throws ReadFailedException { + //TODO implement read after https://jira.fd.io/browse/VPP-468 + } + + @Override + public void merge(@Nonnull final Builder parentBuilder, + @Nonnull final PbbRewriteState readValue) { + ((PbbRewriteStateInterfaceAugmentationBuilder) parentBuilder).setPbbRewriteState(readValue); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/pbb/PbbRewriteCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/pbb/PbbRewriteCustomizerTest.java new file mode 100644 index 000000000..d7ac1151c --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/pbb/PbbRewriteCustomizerTest.java @@ -0,0 +1,296 @@ +package io.fd.honeycomb.translate.v3po.interfaces.pbb; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.translate.vpp.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest; +import io.fd.vpp.jvpp.VppCallbackException; +import io.fd.vpp.jvpp.core.dto.L2InterfacePbbTagRewrite; +import io.fd.vpp.jvpp.core.dto.L2InterfacePbbTagRewriteReply; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pbb.types.rev160704.Operation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev160410.PbbRewriteInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev160410.interfaces._interface.PbbRewrite; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev160410.interfaces._interface.PbbRewriteBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class PbbRewriteCustomizerTest extends WriterCustomizerTest { + + @Captor + private ArgumentCaptor rewriteArgumentCaptor; + + private NamingContext interfaceContext; + private PbbRewriteCustomizer customizer; + private InstanceIdentifier validId; + private InstanceIdentifier invalidId; + + @Override + protected void setUp() throws Exception { + interfaceContext = new NamingContext("interface", "interface-context"); + customizer = new PbbRewriteCustomizer(api, interfaceContext); + + defineMapping(mappingContext, "pbb-interface", 1, "interface-context"); + validId = InstanceIdentifier.create(Interfaces.class) + .child(Interface.class, new InterfaceKey("pbb-interface")) + .augmentation(PbbRewriteInterfaceAugmentation.class) + .child(PbbRewrite.class); + + invalidId = InstanceIdentifier.create(PbbRewrite.class); + } + + @Test + public void testWrite() throws WriteFailedException { + whenRewriteThenSuccess(); + customizer.writeCurrentAttributes(validId, validData(), writeContext); + verifyRewriteRequest(desiredSetResult()); + } + + @Test + public void testWriteFailedCallFailed() { + whenRewriteThenFail(); + final PbbRewrite validData = validData(); + try { + customizer.writeCurrentAttributes(validId, validData, writeContext); + } catch (Exception e) { + assertTrue(e instanceof WriteFailedException.CreateFailedException); + assertTrue(e.getCause() instanceof VppCallbackException); + + final WriteFailedException.CreateFailedException ex = ((WriteFailedException.CreateFailedException) e); + assertEquals(validId, ex.getFailedId()); + assertEquals(validData, ex.getData()); + return; + } + + fail("Test should have failed"); + } + + @Test + public void testWriteFailedInvalidData() { + verifyInvalidWriteDataCombination(invalidDataNoDestination()); + verifyInvalidWriteDataCombination(invalidDataNoSource()); + verifyInvalidWriteDataCombination(invalidDataNoItag()); + verifyInvalidWriteDataCombination(invalidDataNoOperation()); + verifyInvalidWriteDataCombination(invalidDataNoVlan()); + } + + @Test + public void testUpdate() throws WriteFailedException { + whenRewriteThenSuccess(); + final PbbRewrite rewrite = validData(); + customizer.updateCurrentAttributes(validId, rewrite, rewrite, writeContext); + verifyRewriteRequest(desiredSetResult()); + } + + @Test + public void testUpdateFailedCallFailed() { + whenRewriteThenFail(); + final PbbRewrite invalidData = invalidDataNoVlan(); + final PbbRewrite validData = validData(); + try { + customizer.updateCurrentAttributes(validId, invalidData, validData, writeContext); + } catch (Exception e) { + assertTrue(e instanceof WriteFailedException.UpdateFailedException); + assertTrue(e.getCause() instanceof VppCallbackException); + + final WriteFailedException.UpdateFailedException ex = ((WriteFailedException.UpdateFailedException) e); + assertEquals(validId, ex.getFailedId()); + assertEquals(invalidData, ex.getDataBefore()); + assertEquals(validData, ex.getDataAfter()); + return; + } + + fail("Test should have failed"); + } + + @Test + public void testUpdateFailedInvalidData() { + verifyInvalidUpdateDataCombination(invalidDataNoDestination()); + verifyInvalidUpdateDataCombination(invalidDataNoSource()); + verifyInvalidUpdateDataCombination(invalidDataNoItag()); + verifyInvalidUpdateDataCombination(invalidDataNoOperation()); + verifyInvalidUpdateDataCombination(invalidDataNoVlan()); + } + + @Test + public void testDelete() throws WriteFailedException { + whenRewriteThenSuccess(); + customizer.deleteCurrentAttributes(validId, validData(), writeContext); + verifyRewriteRequest(desiredDisableResult()); + } + + @Test + public void testDeleteFailedCallFailed() { + whenRewriteThenFail(); + final PbbRewrite validData = validData(); + try { + customizer.deleteCurrentAttributes(validId, validData, writeContext); + } catch (Exception e) { + assertTrue(e instanceof WriteFailedException.DeleteFailedException); + assertTrue(e.getCause() instanceof VppCallbackException); + assertEquals(validId, ((WriteFailedException.DeleteFailedException) e).getFailedId()); + return; + } + + fail("Test should have failed"); + } + + @Test + public void testDeleteFailedInvalidData() { + verifyInvalidDeleteDataCombination(invalidDataNoDestination()); + verifyInvalidDeleteDataCombination(invalidDataNoSource()); + verifyInvalidDeleteDataCombination(invalidDataNoItag()); + verifyInvalidDeleteDataCombination(invalidDataNoOperation()); + verifyInvalidDeleteDataCombination(invalidDataNoVlan()); + } + + private void whenRewriteThenSuccess() { + when(api.l2InterfacePbbTagRewrite(any())).thenReturn(future(new L2InterfacePbbTagRewriteReply())); + } + + private void whenRewriteThenFail() { + when(api.l2InterfacePbbTagRewrite(any())).thenReturn(failedFuture()); + } + + private void verifyInvalidWriteDataCombination(final PbbRewrite invalidData) { + try { + customizer.writeCurrentAttributes(validId, invalidData, writeContext); + } catch (Exception e) { + assertTrue(e instanceof NullPointerException); + return; + } + + fail("Verifying of invalid combination failed"); + } + + private void verifyInvalidUpdateDataCombination(final PbbRewrite invalidData) { + try { + customizer.updateCurrentAttributes(validId, validData(), invalidData, writeContext); + } catch (Exception e) { + assertTrue(e instanceof NullPointerException); + return; + } + + fail("Verifying of invalid combination failed"); + } + + + private void verifyInvalidDeleteDataCombination(final PbbRewrite invalidData) { + try { + customizer.deleteCurrentAttributes(validId, invalidData, writeContext); + } catch (Exception e) { + assertTrue(e instanceof NullPointerException); + return; + } + + fail("Verifying of invalid combination failed"); + } + + + private L2InterfacePbbTagRewrite desiredSetResult() { + final L2InterfacePbbTagRewrite desiredResult = new L2InterfacePbbTagRewrite(); + desiredResult.swIfIndex = 1; + desiredResult.vtrOp = Operation.Pop2.getIntValue(); + desiredResult.bDmac = new byte[]{-69, -69, -69, -69, -69, -69}; + desiredResult.bSmac = new byte[]{-86, -86, -86, -86, -86, -86}; + desiredResult.bVlanid = 1; + desiredResult.iSid = 2; + + return desiredResult; + } + + private L2InterfacePbbTagRewrite desiredDisableResult() { + final L2InterfacePbbTagRewrite desiredResult = new L2InterfacePbbTagRewrite(); + desiredResult.swIfIndex = 1; + desiredResult.vtrOp = 0; + desiredResult.bDmac = new byte[]{-69, -69, -69, -69, -69, -69}; + desiredResult.bSmac = new byte[]{-86, -86, -86, -86, -86, -86}; + desiredResult.bVlanid = 1; + desiredResult.iSid = 2; + + return desiredResult; + } + + private void verifyRewriteRequest(final L2InterfacePbbTagRewrite desiredResult) { + verify(api, times(1)).l2InterfacePbbTagRewrite(rewriteArgumentCaptor.capture()); + + final L2InterfacePbbTagRewrite actualRequest = rewriteArgumentCaptor.getValue(); + + assertNotNull(actualRequest); + assertEquals(actualRequest.bVlanid, desiredResult.bVlanid); + assertEquals(actualRequest.iSid, desiredResult.iSid); + assertEquals(actualRequest.vtrOp, desiredResult.vtrOp); + assertEquals(actualRequest.outerTag, desiredResult.outerTag); + assertArrayEquals(actualRequest.bDmac, desiredResult.bDmac); + assertArrayEquals(actualRequest.bSmac, desiredResult.bSmac); + } + + private PbbRewrite invalidDataNoDestination() { + return new PbbRewriteBuilder() + .setBVlanTagVlanId(1) + .setITagIsid(2L) + .setSourceAddress(new MacAddress("aa:aa:aa:aa:aa:aa")) + .setInterfaceOperation(Operation.Pop2) + .build(); + } + + private PbbRewrite invalidDataNoSource() { + return new PbbRewriteBuilder() + .setBVlanTagVlanId(1) + .setITagIsid(2L) + .setDestinationAddress(new MacAddress("bb:bb:bb:bb:bb:bb")) + .setInterfaceOperation(Operation.Pop2) + .build(); + } + + private PbbRewrite invalidDataNoItag() { + return new PbbRewriteBuilder() + .setBVlanTagVlanId(1) + .setSourceAddress(new MacAddress("aa:aa:aa:aa:aa:aa")) + .setDestinationAddress(new MacAddress("bb:bb:bb:bb:bb:bb")) + .setInterfaceOperation(Operation.Pop2) + .build(); + } + + private PbbRewrite invalidDataNoVlan() { + return new PbbRewriteBuilder() + .setITagIsid(2L) + .setSourceAddress(new MacAddress("aa:aa:aa:aa:aa:aa")) + .setDestinationAddress(new MacAddress("bb:bb:bb:bb:bb:bb")) + .setInterfaceOperation(Operation.Pop2) + .build(); + } + + private PbbRewrite invalidDataNoOperation() { + return new PbbRewriteBuilder() + .setITagIsid(2L) + .setSourceAddress(new MacAddress("aa:aa:aa:aa:aa:aa")) + .setDestinationAddress(new MacAddress("bb:bb:bb:bb:bb:bb")) + .setInterfaceOperation(Operation.Pop2) + .build(); + } + + private PbbRewrite validData() { + return new PbbRewriteBuilder() + .setBVlanTagVlanId(1) + .setITagIsid(2L) + .setSourceAddress(new MacAddress("aa:aa:aa:aa:aa:aa")) + .setDestinationAddress(new MacAddress("bb:bb:bb:bb:bb:bb")) + .setInterfaceOperation(Operation.Pop2) + .build(); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/pbb/PbbRewriteStateCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/pbb/PbbRewriteStateCustomizerTest.java new file mode 100644 index 000000000..a5c9680aa --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/pbb/PbbRewriteStateCustomizerTest.java @@ -0,0 +1,19 @@ +package io.fd.honeycomb.translate.v3po.interfacesstate.pbb; + +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.honeycomb.vpp.test.read.ReaderCustomizerTest; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev160410.PbbRewriteStateInterfaceAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev160410.interfaces.state._interface.PbbRewriteState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev160410.interfaces.state._interface.PbbRewriteStateBuilder; + +public class PbbRewriteStateCustomizerTest extends ReaderCustomizerTest { + + public PbbRewriteStateCustomizerTest() { + super(PbbRewriteState.class, PbbRewriteStateInterfaceAugmentationBuilder.class); + } + + @Override + protected ReaderCustomizer initCustomizer() { + return new PbbRewriteStateCustomizer(api); + } +} -- cgit 1.2.3-korg