From 9f3503ac117d485d75e604364647d7f59401f24a Mon Sep 17 00:00:00 2001 From: Jan Srnicek Date: Fri, 12 May 2017 13:15:50 +0200 Subject: HC2VPP-144 - Sub-interface span Provides option to define port mirroring from interface to subinterface Change-Id: I8c04e8eb6b980c830e77e1ef2b75ddff3d59364c Signed-off-by: Jan Srnicek Signed-off-by: jsrnicek Signed-off-by: Jan Srnicek --- v3po/api/src/main/yang/subinterface-span.yang | 40 ++++++ v3po/span_postman_collection.json | 160 +++++++++++++++++++++ .../v3po/factory/InterfacesStateReaderFactory.java | 4 +- .../v3po/factory/InterfacesWriterFactory.java | 4 +- .../SubinterfaceAugmentationWriterFactory.java | 15 ++ ...SubinterfaceStateAugmentationReaderFactory.java | 16 +++ .../span/MirroredInterfaceCustomizer.java | 55 ++++--- .../span/AbstractMirroredInterfacesCustomizer.java | 114 +++++++++++++++ .../InterfaceMirroredInterfacesCustomizer.java | 61 ++++++++ .../span/MirroredInterfacesCustomizer.java | 131 ----------------- .../SubInterfaceMirroredInterfacesCustomizer.java | 64 +++++++++ .../io/fd/hc2vpp/v3po/util/SubInterfaceUtils.java | 5 +- .../span/MirroredInterfaceCustomizerTest.java | 115 --------------- .../span/MirroredInterfacesCustomizerTest.java | 116 +++++++++++++++ .../span/MirroredInterfacesCustomizerTest.java | 2 +- 15 files changed, 625 insertions(+), 277 deletions(-) create mode 100644 v3po/api/src/main/yang/subinterface-span.yang create mode 100644 v3po/span_postman_collection.json create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/AbstractMirroredInterfacesCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/InterfaceMirroredInterfacesCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/MirroredInterfacesCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/SubInterfaceMirroredInterfacesCustomizer.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfaceCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfacesCustomizerTest.java (limited to 'v3po') diff --git a/v3po/api/src/main/yang/subinterface-span.yang b/v3po/api/src/main/yang/subinterface-span.yang new file mode 100644 index 000000000..74d33f57c --- /dev/null +++ b/v3po/api/src/main/yang/subinterface-span.yang @@ -0,0 +1,40 @@ +module subinterface-span { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:subinterface-span"; + prefix "subif-span"; + + revision "2017-05-10" { + description + "Initialial revision that adds support for mirroring interfaces on subinterfaces. + Vpp implementation allows/implements only two cases: + - Src: interface |Dst: interface - covered in v3po.yang + - Src: interface |Dst: subinterface - covered by this model"; + } + + import v3po { + prefix "v3po"; + } + + import vpp-vlan { + prefix "vpp-vlan"; + } + + import yang-ext { + prefix "ext"; + } + + augment /if:interfaces/if:interface/vpp-vlan:sub-interfaces/vpp-vlan:sub-interface { + ext:augment-identifier "vpp-subinterface-span-augmentation"; + + container span { + uses v3po:span-attributes; + } + } + + augment /if:interfaces-state/if:interface/vpp-vlan:sub-interfaces/vpp-vlan:sub-interface { + ext:augment-identifier "vpp-subinterface-span-state-augmentation"; + container span-state { + uses v3po:span-attributes; + } + } +} \ No newline at end of file diff --git a/v3po/span_postman_collection.json b/v3po/span_postman_collection.json new file mode 100644 index 000000000..412b44940 --- /dev/null +++ b/v3po/span_postman_collection.json @@ -0,0 +1,160 @@ +{ + "id": "b30b26ab-fd5f-368f-713a-4c72315cf663", + "name": "Span interface/subinterface collection", + "description": "Provides model request to define pot mirroring for interfaces and sub-interfaces", + "order": [], + "folders": [ + { + "id": "cc874576-92fd-fa49-20fe-482333b895c0", + "name": "Interface <==> Interface", + "description": "", + "order": [ + "b2342499-fbb3-02d1-bc7d-3c7d515b8cfa", + "67359961-1edf-d25f-63d2-ff84552da924", + "67a1966d-ec28-c131-7fdf-0d8e24ac2b42" + ], + "owner": 0 + }, + { + "id": "d26fa438-e4f6-ad96-b92a-ebb509d4ca66", + "name": "Interface <==> SubInterface", + "description": "", + "order": [ + "ffd3adcd-345f-d8fb-0393-22ad78528083", + "03a5c3d7-e3c1-0862-4a4c-806ac7282cb5", + "59ae66fd-bd64-e0bd-924c-b9469db447af" + ], + "owner": 0 + } + ], + "timestamp": 1494480653049, + "owner": 0, + "public": false, + "requests": [ + { + "id": "03a5c3d7-e3c1-0862-4a4c-806ac7282cb5", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/operational/ietf-interfaces:interfaces-state/interface/GigabitEthernet0%2F8%2F0/vpp-vlan:sub-interfaces/sub-interface/1/span-state", + "preRequestScript": "", + "pathVariables": {}, + "method": "GET", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1494481976252, + "name": "Read port mirroring", + "description": "set span src local0 dst GigabiteEthernet0/8/0", + "collectionId": "b30b26ab-fd5f-368f-713a-4c72315cf663", + "responses": [], + "rawModeData": "{\r\n \r\n \"span\": {\r\n \t\"mirrored-interfaces\": {\r\n \t\t\"mirrored-interface\": [{\"iface-ref\":\"GigabitEthernet0/8/0\",\"state\":\"receive\"}]\r\n \t}\r\n }\r\n \r\n}" + }, + { + "id": "59ae66fd-bd64-e0bd-924c-b9469db447af", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/config/ietf-interfaces:interfaces/interface/GigabitEthernet0%2F8%2F0/vpp-vlan:sub-interfaces/sub-interface/1/span", + "preRequestScript": "", + "pathVariables": {}, + "method": "DELETE", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1494481990266, + "name": "Delete port mirroring", + "description": "set span src local0 dst GigabiteEthernet0/8/0", + "collectionId": "b30b26ab-fd5f-368f-713a-4c72315cf663", + "responses": [], + "rawModeData": "{\r\n \r\n \"span\": {\r\n \t\"mirrored-interfaces\": {\r\n \t\t\"mirrored-interface\": [{\"iface-ref\":\"GigabitEthernet0/8/0\",\"state\":\"receive\"}]\r\n \t}\r\n }\r\n \r\n}" + }, + { + "id": "67359961-1edf-d25f-63d2-ff84552da924", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/operational/ietf-interfaces:interfaces-state/interface/GigabitEthernet0%2F8%2F0/span", + "preRequestScript": "", + "pathVariables": {}, + "method": "GET", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1477908227905, + "name": "Read port mirroring", + "description": "show span", + "collectionId": "b30b26ab-fd5f-368f-713a-4c72315cf663", + "responses": [], + "rawModeData": "", + "folder": "cc874576-92fd-fa49-20fe-482333b895c0", + "isFromCollection": true, + "collectionRequestId": "67359961-1edf-d25f-63d2-ff84552da924" + }, + { + "id": "67a1966d-ec28-c131-7fdf-0d8e24ac2b42", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/config/ietf-interfaces:interfaces/interface/GigabitEthernet0%2F8%2F0/span", + "preRequestScript": "", + "pathVariables": {}, + "method": "DELETE", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1477907954064, + "name": "Delete port mirroring local0 -> GigabiteEthernet0/8/0", + "description": "", + "collectionId": "b30b26ab-fd5f-368f-713a-4c72315cf663", + "responses": [], + "rawModeData": "", + "folder": "cc874576-92fd-fa49-20fe-482333b895c0" + }, + { + "id": "b2342499-fbb3-02d1-bc7d-3c7d515b8cfa", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/config/ietf-interfaces:interfaces/interface/GigabitEthernet0%2F8%2F0/span", + "preRequestScript": "", + "pathVariables": {}, + "method": "PUT", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1477905258870, + "name": "Set port mirroring local0 -> GigabiteEthernet0/8/0", + "description": "set span src local0 dst GigabiteEthernet0/8/0", + "collectionId": "b30b26ab-fd5f-368f-713a-4c72315cf663", + "responses": [], + "rawModeData": "{\r\n \r\n \"span\": {\r\n \t\"mirrored-interfaces\": {\r\n \t\t\"mirrored-interface\": [{\"iface-ref\":\"local0\",\"state\":\"receive\"}]\r\n \t}\r\n }\r\n \r\n}", + "folder": "cc874576-92fd-fa49-20fe-482333b895c0" + }, + { + "id": "ffd3adcd-345f-d8fb-0393-22ad78528083", + "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", + "url": "http://localhost:8183/restconf/config/ietf-interfaces:interfaces/interface/GigabitEthernet0%2F8%2F0/vpp-vlan:sub-interfaces/sub-interface/1/span", + "preRequestScript": "", + "pathVariables": {}, + "method": "PUT", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1494481863201, + "name": "Set port mirroring GigabitEthernet0/8/0 to GigabitEthernet0/8/0.1", + "description": "set span src local0 dst GigabiteEthernet0/8/0", + "collectionId": "b30b26ab-fd5f-368f-713a-4c72315cf663", + "responses": [], + "rawModeData": "{\r\n \r\n \"span\": {\r\n \t\"mirrored-interfaces\": {\r\n \t\t\"mirrored-interface\": [{\"iface-ref\":\"GigabitEthernet0/8/0\",\"state\":\"receive\"}]\r\n \t}\r\n }\r\n \r\n}" + } + ] +} \ No newline at end of file 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 e75f97d93..3d78094a3 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 @@ -31,7 +31,7 @@ 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.pbb.PbbRewriteStateCustomizer; -import io.fd.hc2vpp.v3po.interfacesstate.span.MirroredInterfacesCustomizer; +import io.fd.hc2vpp.v3po.interfacesstate.span.InterfaceMirroredInterfacesCustomizer; import io.fd.honeycomb.translate.impl.read.GenericInitListReader; import io.fd.honeycomb.translate.impl.read.GenericInitReader; import io.fd.honeycomb.translate.impl.read.GenericReader; @@ -130,7 +130,7 @@ public final class InterfacesStateReaderFactory implements ReaderFactory { registry.subtreeAdd( ImmutableSet.of(InstanceIdentifier.create(MirroredInterfaces.class).child(MirroredInterface.class)), new GenericInitReader<>(spanId.child(MirroredInterfaces.class), - new MirroredInterfacesCustomizer(jvpp, ifcNamingCtx))); + new InterfaceMirroredInterfacesCustomizer(jvpp, ifcNamingCtx))); } private void initPbbRewriteAugmentation(final ModifiableReaderRegistryBuilder registry, diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesWriterFactory.java index 7fba6360a..6b9d514f2 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesWriterFactory.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesWriterFactory.java @@ -141,8 +141,8 @@ public final class InterfacesWriterFactory implements WriterFactory { .child(Span.class) .child(MirroredInterfaces.class) .child(MirroredInterface.class); - registry.addAfter(new GenericWriter<>(mirroredIfcId, new MirroredInterfaceCustomizer(jvpp, ifcNamingContext)), - ifcId); + registry.addAfter(new GenericWriter<>(mirroredIfcId, new MirroredInterfaceCustomizer(jvpp, ifcNamingContext, + id -> id.firstKeyOf(Interface.class).getName())), ifcId); } private void addPbbAugmentationWriters(final InstanceIdentifier ifcId, diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceAugmentationWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceAugmentationWriterFactory.java index be202f6fa..8c412b5e2 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceAugmentationWriterFactory.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceAugmentationWriterFactory.java @@ -24,12 +24,18 @@ import io.fd.hc2vpp.v3po.interfaces.RewriteCustomizer; import io.fd.hc2vpp.v3po.interfaces.SubInterfaceCustomizer; import io.fd.hc2vpp.v3po.interfaces.SubInterfaceL2Customizer; import io.fd.hc2vpp.v3po.interfaces.SubInterfaceRoutingCustomizer; +import io.fd.hc2vpp.v3po.interfaces.span.MirroredInterfaceCustomizer; +import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; import io.fd.honeycomb.translate.impl.write.GenericListWriter; import io.fd.honeycomb.translate.impl.write.GenericWriter; import io.fd.honeycomb.translate.write.WriterFactory; import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; import io.fd.vpp.jvpp.core.future.FutureJVppCore; import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.or.any.Dot1qTag; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.subinterface.span.rev170510.VppSubinterfaceSpanAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.subinterface.span.rev170510.interfaces._interface.sub.interfaces.sub._interface.Span; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.MirroredInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.mirrored.interfaces.MirroredInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170509.SubinterfaceAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170509.interfaces._interface.SubInterfaces; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170509.interfaces._interface.sub.interfaces.SubInterface; @@ -95,5 +101,14 @@ public final class SubinterfaceAugmentationWriterFactory implements WriterFactor L2_ID); final InstanceIdentifier routingId = SUB_IFC_ID.child(Routing.class); registry.add(new GenericWriter<>(routingId, new SubInterfaceRoutingCustomizer(jvpp, ifcContext))); + + final InstanceIdentifier mirroredId = + SUB_IFC_ID.augmentation(VppSubinterfaceSpanAugmentation.class) + .child(Span.class) + .child(MirroredInterfaces.class) + .child(MirroredInterface.class); + registry.addAfter(new GenericListWriter<>(mirroredId, + new MirroredInterfaceCustomizer(jvpp, ifcContext, SubInterfaceUtils::subInterfaceFullNameConfig)), + SUB_IFC_ID); } } 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 9a6619838..ee1fd6034 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.span.SubInterfaceMirroredInterfacesCustomizer; import io.fd.honeycomb.translate.impl.read.GenericInitListReader; import io.fd.honeycomb.translate.impl.read.GenericInitReader; import io.fd.honeycomb.translate.impl.read.GenericReader; @@ -31,6 +32,11 @@ import io.fd.honeycomb.translate.read.ReaderFactory; import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; import io.fd.vpp.jvpp.core.future.FutureJVppCore; import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.or.any.Dot1qTag; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.subinterface.span.rev170510.VppSubinterfaceSpanStateAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.subinterface.span.rev170510.VppSubinterfaceSpanStateAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.subinterface.span.rev170510.interfaces.state._interface.sub.interfaces.sub._interface.SpanState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.subinterface.span.rev170510.interfaces.state._interface.sub.interfaces.sub._interface.SpanStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.MirroredInterfaces; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170509.SubinterfaceStateAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170509.SubinterfaceStateAugmentationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170509.interfaces.state._interface.SubInterfaces; @@ -91,5 +97,15 @@ public final class SubinterfaceStateAugmentationReaderFactory implements ReaderF new GenericReader<>(l2Id.child(Rewrite.class), new RewriteCustomizer(jvpp, ifcCtx))); final InstanceIdentifier routingId = subIfcId.child(Routing.class); registry.add(new GenericReader<>(routingId, new SubInterfaceRoutingCustomizer(jvpp, ifcCtx))); + + final InstanceIdentifier spanStateAugId = subIfcId.augmentation(VppSubinterfaceSpanStateAugmentation.class); + registry.addStructuralReader(spanStateAugId, VppSubinterfaceSpanStateAugmentationBuilder.class); + + final InstanceIdentifier spanStateId = spanStateAugId + .child(SpanState.class); + registry.addStructuralReader(spanStateId, SpanStateBuilder.class); + + final InstanceIdentifier mirroredInterfacesId = spanStateId.child(MirroredInterfaces.class); + registry.add(new GenericInitReader<>(mirroredInterfacesId, new SubInterfaceMirroredInterfacesCustomizer(jvpp, ifcCtx))); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfaceCustomizer.java index 993120b68..4d6ea9864 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfaceCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfaceCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Cisco and/or its affiliates. + * 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. @@ -16,6 +16,8 @@ package io.fd.hc2vpp.v3po.interfaces.span; +import static io.fd.honeycomb.translate.util.RWUtils.cutId; + import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; import io.fd.hc2vpp.common.translate.util.NamingContext; @@ -24,48 +26,41 @@ import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; import io.fd.vpp.jvpp.core.dto.SwInterfaceSpanEnableDisable; import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.function.Function; import javax.annotation.Nonnull; import javax.annotation.Nullable; -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.v3po.rev170315.SpanState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.MirroredInterfaces; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.mirrored.interfaces.MirroredInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.mirrored.interfaces.MirroredInterfaceKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public final class MirroredInterfaceCustomizer - extends FutureJVppCustomizer +public final class MirroredInterfaceCustomizer extends FutureJVppCustomizer implements ListWriterCustomizer, JvppReplyConsumer { private static final Logger LOG = LoggerFactory.getLogger(MirroredInterfaceCustomizer.class); private final NamingContext ifcContext; + private final Function, String> destinationInterfaceNameExtractor; - public MirroredInterfaceCustomizer(@Nonnull final FutureJVppCore futureJVppCore, final NamingContext ifcContext) { + public MirroredInterfaceCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext ifcContext, + @Nonnull final Function, String> destinationInterfaceNameExtractor) { super(futureJVppCore); this.ifcContext = ifcContext; + this.destinationInterfaceNameExtractor = destinationInterfaceNameExtractor; } - private SwInterfaceSpanEnableDisable getSpanAddDelRequest(final int dstId, final Integer srcId, final boolean isAdd, - @Nullable final SpanState state) { - final SwInterfaceSpanEnableDisable spanAddDel = new SwInterfaceSpanEnableDisable(); - spanAddDel.state = (byte) (isAdd - ? state != null - ? state.getIntValue() - : 0 - : 0);// either one of 1(rx),2(tx),3(both) or 0 for disable/delete - spanAddDel.swIfIndexFrom = srcId; - spanAddDel.swIfIndexTo = dstId; - return spanAddDel; - } @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier instanceIdentifier, + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final MirroredInterface mirroredInterface, @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String destinationInterfaceName = instanceIdentifier.firstKeyOf(Interface.class).getName(); + final String destinationInterfaceName = + destinationInterfaceNameExtractor.apply(cutId(id, MirroredInterfaces.class)); final String sourceInterfaceName = mirroredInterface.getIfaceRef(); final SpanState spanState = mirroredInterface.getState(); @@ -78,7 +73,7 @@ public final class MirroredInterfaceCustomizer interfaceId(writeContext, ifcContext, sourceInterfaceName), true, spanState)) - .toCompletableFuture(), instanceIdentifier); + .toCompletableFuture(), id); LOG.debug("Span for source interface {} | destination interface {} | state {} successfully enabled", sourceInterfaceName, destinationInterfaceName, spanState); } @@ -94,10 +89,11 @@ public final class MirroredInterfaceCustomizer } @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier instanceIdentifier, + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final MirroredInterface mirroredInterface, @Nonnull final WriteContext writeContext) throws WriteFailedException { - final String destinationInterfaceName = instanceIdentifier.firstKeyOf(Interface.class).getName(); + final String destinationInterfaceName = + destinationInterfaceNameExtractor.apply(cutId(id, MirroredInterfaces.class)); final String sourceInterfaceName = mirroredInterface.getIfaceRef(); LOG.debug("Disabling span for source interface {} | destination interface {} ", sourceInterfaceName, destinationInterfaceName); @@ -108,11 +104,24 @@ public final class MirroredInterfaceCustomizer interfaceId(writeContext, ifcContext, sourceInterfaceName), false, null)) - .toCompletableFuture(), instanceIdentifier); + .toCompletableFuture(), id); LOG.debug("Span for source interface {} | destination interface {} successfully disabled", sourceInterfaceName, destinationInterfaceName); } + private SwInterfaceSpanEnableDisable getSpanAddDelRequest(final int dstId, final Integer srcId, final boolean isAdd, + @Nullable final SpanState state) { + final SwInterfaceSpanEnableDisable spanAddDel = new SwInterfaceSpanEnableDisable(); + spanAddDel.state = (byte) (isAdd + ? state != null + ? state.getIntValue() + : 0 + : 0);// either one of 1(rx),2(tx),3(both) or 0 for disable/delete + spanAddDel.swIfIndexFrom = srcId; + spanAddDel.swIfIndexTo = dstId; + return spanAddDel; + } + private static int interfaceId(final WriteContext writeContext, final NamingContext ifcContext, final String name) { return ifcContext.getIndex(name, writeContext.getMappingContext()); } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/AbstractMirroredInterfacesCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/AbstractMirroredInterfacesCustomizer.java new file mode 100644 index 000000000..fbfbf67a4 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/AbstractMirroredInterfacesCustomizer.java @@ -0,0 +1,114 @@ +/* + * 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.hc2vpp.v3po.interfacesstate.span; + +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.MappingContext; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSpanDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSpanDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.SpanState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.MirroredInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.MirroredInterfacesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.mirrored.interfaces.MirroredInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.mirrored.interfaces.MirroredInterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.mirrored.interfaces.MirroredInterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +abstract class AbstractMirroredInterfacesCustomizer + extends FutureJVppCustomizer + implements InitializingReaderCustomizer, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(AbstractMirroredInterfacesCustomizer.class); + + private final NamingContext ifcContext; + private final Function, String> destinationInterfaceNameExtractor; + + protected AbstractMirroredInterfacesCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext ifcContext, + @Nonnull final Function, String> destinationInterfaceNameExtractor) { + super(futureJVppCore); + this.ifcContext = ifcContext; + this.destinationInterfaceNameExtractor = destinationInterfaceNameExtractor; + } + + @Nonnull + @Override + public MirroredInterfacesBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new MirroredInterfacesBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final MirroredInterfacesBuilder builder, @Nonnull final ReadContext ctx) + throws ReadFailedException { + LOG.trace("Reading mirrored interfaces under: {}", id); + final int dstId = destinationInterfaceIndex(id, ctx.getMappingContext()); + + final SwInterfaceSpanDetailsReplyDump replyForRead; + if (ctx.getModificationCache().containsKey(getCacheKey())) { + replyForRead = (SwInterfaceSpanDetailsReplyDump) ctx.getModificationCache().get(getCacheKey()); + } else { + replyForRead = getReplyForRead(getFutureJVpp().swInterfaceSpanDump( + new SwInterfaceSpanDump()).toCompletableFuture(), id); + ctx.getModificationCache().put(getCacheKey(), replyForRead); + } + + final List mirroredInterfaces = + replyForRead.swInterfaceSpanDetails.stream() + .filter(detail -> detail.swIfIndexTo == dstId) + .filter(detail -> detail.state != 0) // filters disabled(we use disabled as delete) + .map(detail -> { + final String interfaceName = + ifcContext.getName(detail.swIfIndexFrom, ctx.getMappingContext()); + return new MirroredInterfaceBuilder() + .setIfaceRef(interfaceName) + .setKey(new MirroredInterfaceKey(interfaceName)) + .setState(SpanState.forValue(detail.state)) + .build(); + } + ) + .collect(Collectors.toList()); + + LOG.debug("Mirrored interfaces for: {} read as: {}", id, mirroredInterfaces); + + if (!mirroredInterfaces.isEmpty()) { + builder.setMirroredInterface(mirroredInterfaces); + } + } + + private String getCacheKey() { + return getClass().getName(); + } + + private int destinationInterfaceIndex(@Nonnull final InstanceIdentifier id, + @Nonnull final MappingContext mappingContext) { + final String destinationInterfaceName = destinationInterfaceNameExtractor.apply(id); + return ifcContext.getIndex(destinationInterfaceName, mappingContext); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/InterfaceMirroredInterfacesCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/InterfaceMirroredInterfacesCustomizer.java new file mode 100644 index 000000000..9f05c61df --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/InterfaceMirroredInterfacesCustomizer.java @@ -0,0 +1,61 @@ +/* + * 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.span; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.InterfaceCustomizer; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.util.RWUtils; +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.opendaylight.params.xml.ns.yang.v3po.rev170315.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.interfaces.state._interface.SpanBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.MirroredInterfaces; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Provides interface-specific logic to read/init port mirroring configuration + */ +public class InterfaceMirroredInterfacesCustomizer extends AbstractMirroredInterfacesCustomizer { + + public InterfaceMirroredInterfacesCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext ifcContext) { + super(futureJVppCore, ifcContext, id -> id.firstKeyOf(Interface.class).getName()); + } + + @Nonnull + @Override + public Initialized init(@Nonnull final InstanceIdentifier id, + @Nonnull final MirroredInterfaces readValue, + @Nonnull final ReadContext ctx) { + final InstanceIdentifier cfgId = + InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) + .augmentation(VppInterfaceAugmentation.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.interfaces._interface.Span.class) + .child(MirroredInterfaces.class); + return Initialized.create(cfgId, readValue); + } + + @Override + public void merge(@Nonnull Builder builder, @Nonnull MirroredInterfaces mirroredInterfaces) { + ((SpanBuilder) builder).setMirroredInterfaces(mirroredInterfaces); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/MirroredInterfacesCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/MirroredInterfacesCustomizer.java deleted file mode 100644 index 229ed6948..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/MirroredInterfacesCustomizer.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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.hc2vpp.v3po.interfacesstate.span; - -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.InterfaceCustomizer; -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.SwInterfaceSpanDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSpanDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.List; -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.state.Interface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.SpanState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.interfaces._interface.Span; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.interfaces.state._interface.SpanBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.MirroredInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.MirroredInterfacesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.mirrored.interfaces.MirroredInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.mirrored.interfaces.MirroredInterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.mirrored.interfaces.MirroredInterfaceKey; -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 final class MirroredInterfacesCustomizer - extends FutureJVppCustomizer - implements InitializingReaderCustomizer, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(MirroredInterfacesCustomizer.class); - - private final NamingContext ifcContext; - - public MirroredInterfacesCustomizer(@Nonnull final FutureJVppCore futureJVppCore, final NamingContext ifcContext) { - super(futureJVppCore); - this.ifcContext = ifcContext; - } - - @Nonnull - @Override - public MirroredInterfacesBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new MirroredInterfacesBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final MirroredInterfacesBuilder builder, @Nonnull final ReadContext ctx) - throws ReadFailedException { - LOG.trace("Reading mirrored interfaces under: {}", id); - final int dstId = - ifcContext.getIndex(id.firstKeyOf(Interface.class).getName(), ctx.getMappingContext()); - - final SwInterfaceSpanDetailsReplyDump replyForRead; - if (ctx.getModificationCache().containsKey(getCacheKey())) { - replyForRead = (SwInterfaceSpanDetailsReplyDump) ctx.getModificationCache().get(getCacheKey()); - } else { - replyForRead = getReplyForRead(getFutureJVpp().swInterfaceSpanDump( - new SwInterfaceSpanDump()).toCompletableFuture(), id); - ctx.getModificationCache().put(getCacheKey(), replyForRead); - } - - final List mirroredInterfaces = - replyForRead.swInterfaceSpanDetails.stream() - .filter(detail -> detail.swIfIndexTo == dstId) - .filter(detail -> detail.state != 0) // filters disabled(we use disabled as delete) - .map(detail -> { - final String interfaceName = - ifcContext.getName(detail.swIfIndexFrom, ctx.getMappingContext()); - return new MirroredInterfaceBuilder() - .setIfaceRef(interfaceName) - .setKey(new MirroredInterfaceKey(interfaceName)) - .setState(SpanState.forValue(detail.state)) - .build(); - } - ) - .collect(Collectors.toList()); - - LOG.debug("Mirrored interfaces for: {} read as: {}", id, mirroredInterfaces); - - if (!mirroredInterfaces.isEmpty()) { - builder.setMirroredInterface(mirroredInterfaces); - } - } - - private String getCacheKey() { - return getClass().getName(); - } - - @Override - public void merge(@Nonnull final Builder parentBuilder, - @Nonnull final MirroredInterfaces readValue) { - ((SpanBuilder) parentBuilder).setMirroredInterfaces(readValue); - } - - @Nonnull - @Override - public Initialized init(@Nonnull final InstanceIdentifier id, - @Nonnull final MirroredInterfaces readValue, - @Nonnull final ReadContext ctx) { - final InstanceIdentifier cfgId = - InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class)) - .augmentation(VppInterfaceAugmentation.class) - .child(Span.class) - .child(MirroredInterfaces.class); - return Initialized.create(cfgId, readValue); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/SubInterfaceMirroredInterfacesCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/SubInterfaceMirroredInterfacesCustomizer.java new file mode 100644 index 000000000..8d3557f96 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/span/SubInterfaceMirroredInterfacesCustomizer.java @@ -0,0 +1,64 @@ +/* + * 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.span; + + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfacesstate.SubInterfaceCustomizer; +import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.subinterface.span.rev170510.VppSubinterfaceSpanAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.subinterface.span.rev170510.interfaces._interface.sub.interfaces.sub._interface.Span; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.subinterface.span.rev170510.interfaces.state._interface.sub.interfaces.sub._interface.SpanStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.MirroredInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170509.interfaces.state._interface.sub.interfaces.SubInterface; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Provides sub-interface-specific logic to read/init port mirroring configuration + */ +public class SubInterfaceMirroredInterfacesCustomizer extends AbstractMirroredInterfacesCustomizer { + + public SubInterfaceMirroredInterfacesCustomizer(@Nonnull FutureJVppCore futureJVppCore, NamingContext ifcContext) { + super(futureJVppCore, ifcContext, SubInterfaceUtils::subInterfaceFullNameOperational); + } + + @Nonnull + @Override + public Initialized init(@Nonnull InstanceIdentifier id, + @Nonnull MirroredInterfaces readValue, + @Nonnull ReadContext readContext) { + final InstanceIdentifier cfgId = + SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class)) + .augmentation(VppSubinterfaceSpanAugmentation.class) + .child(Span.class) + .child(MirroredInterfaces.class); + + return Initialized.create(cfgId, readValue); + } + + @Override + public void merge(@Nonnull Builder builder, @Nonnull MirroredInterfaces mirroredInterfaces) { + ((SpanStateBuilder) builder).setMirroredInterfaces(mirroredInterfaces); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/util/SubInterfaceUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/util/SubInterfaceUtils.java index 7b83aafec..6fdf2e12d 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/util/SubInterfaceUtils.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/util/SubInterfaceUtils.java @@ -26,7 +26,6 @@ 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.rev170509.interfaces._interface.sub.interfaces.SubInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170509.sub._interface.base.attributes.Tags; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170509.sub._interface.base.attributes.tags.Tag; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev170509.sub._interface.routing.attributes.Routing; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public final class SubInterfaceUtils { @@ -39,7 +38,7 @@ public final class SubInterfaceUtils { return String.format("%s.%d", superIfName, subIfaceId); } - public static String subInterfaceFullNameConfig(final @Nonnull InstanceIdentifier instanceIdentifier) { + public static String subInterfaceFullNameConfig(final @Nonnull InstanceIdentifier instanceIdentifier) { final String parentInterfaceName = checkNotNull(instanceIdentifier.firstKeyOf(Interface.class), "Configuration identifier expected") .getName(); @@ -47,7 +46,7 @@ public final class SubInterfaceUtils { return SubInterfaceUtils.getSubInterfaceName(parentInterfaceName, subIfId.intValue()); } - public static String subInterfaceFullNameOperational(final @Nonnull InstanceIdentifier instanceIdentifier) { + public static String subInterfaceFullNameOperational(final @Nonnull InstanceIdentifier instanceIdentifier) { final String parentInterfaceName = checkNotNull(instanceIdentifier.firstKeyOf( org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class), "Operational identifier expected").getName(); diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfaceCustomizerTest.java deleted file mode 100644 index 38e076f37..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfaceCustomizerTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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.hc2vpp.v3po.interfaces.span; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSpanEnableDisable; -import io.fd.vpp.jvpp.core.dto.SwInterfaceSpanEnableDisableReply; -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.opendaylight.params.xml.ns.yang.v3po.rev170315.SpanState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.interfaces._interface.Span; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.MirroredInterfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.mirrored.interfaces.MirroredInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.mirrored.interfaces.MirroredInterfaceBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class MirroredInterfaceCustomizerTest extends WriterCustomizerTest { - - private static final String IFACE_NAME = "iface"; - private static final int IFACE_INDEX = 3; - private static final String SRC_IFACE_NAME = "src-iface"; - private static final int SRC_IFACE_INDEX = 5; - - private NamingContext interfaceContext; - private MirroredInterfaceCustomizer customizer; - - private InstanceIdentifier validId; - private MirroredInterface validData; - - @Captor - private ArgumentCaptor requestCaptor; - - public void setUpTest() { - interfaceContext = new NamingContext("iface", "iface-context"); - customizer = new MirroredInterfaceCustomizer(api, interfaceContext); - defineMapping(mappingContext, IFACE_NAME, IFACE_INDEX, "iface-context"); - defineMapping(mappingContext, SRC_IFACE_NAME, SRC_IFACE_INDEX, "iface-context"); - - validId = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) - .augmentation(VppInterfaceAugmentation.class).child(Span.class) - .child(MirroredInterfaces.class) - .child(MirroredInterface.class); - - validData = new MirroredInterfaceBuilder() - .setIfaceRef(SRC_IFACE_NAME) - .setState(SpanState.Receive) - .build(); - - when(api.swInterfaceSpanEnableDisable(any())).thenReturn(future(new SwInterfaceSpanEnableDisableReply())); - } - - @Test - public void writeCurrentAttributes() throws Exception { - customizer.writeCurrentAttributes(validId, validData, writeContext); - verify(api, times(1)).swInterfaceSpanEnableDisable(requestCaptor.capture()); - assertCreateRequest(requestCaptor.getValue()); - } - - @Test - public void updateCurrentAttributes() throws Exception { - customizer.updateCurrentAttributes(validId, validData, validData, writeContext); - verify(api, times(2)).swInterfaceSpanEnableDisable(requestCaptor.capture()); - assertDeleteRequest(requestCaptor.getAllValues().get(0)); - assertCreateRequest(requestCaptor.getAllValues().get(1)); - } - - @Test - public void deleteCurrentAttributes() throws Exception { - customizer.deleteCurrentAttributes(validId, validData, writeContext); - verify(api, times(1)).swInterfaceSpanEnableDisable(requestCaptor.capture()); - assertDeleteRequest(requestCaptor.getValue()); - } - - private static void assertCreateRequest(final SwInterfaceSpanEnableDisable createRequest) { - assertNotNull(createRequest); - assertEquals(1, createRequest.state); - assertEquals(IFACE_INDEX, createRequest.swIfIndexTo); - assertEquals(SRC_IFACE_INDEX, createRequest.swIfIndexFrom); - } - - private static void assertDeleteRequest(final SwInterfaceSpanEnableDisable deleteRequest) { - assertNotNull(deleteRequest); - assertEquals(0, deleteRequest.state); - assertEquals(IFACE_INDEX, deleteRequest.swIfIndexTo); - assertEquals(SRC_IFACE_INDEX, deleteRequest.swIfIndexFrom); - } - -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfacesCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfacesCustomizerTest.java new file mode 100644 index 000000000..e1b21ffce --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfacesCustomizerTest.java @@ -0,0 +1,116 @@ +/* + * 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.hc2vpp.v3po.interfaces.span; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSpanEnableDisable; +import io.fd.vpp.jvpp.core.dto.SwInterfaceSpanEnableDisableReply; +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.opendaylight.params.xml.ns.yang.v3po.rev170315.SpanState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.interfaces._interface.Span; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.MirroredInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.mirrored.interfaces.MirroredInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.span.attributes.mirrored.interfaces.MirroredInterfaceBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class MirroredInterfacesCustomizerTest extends WriterCustomizerTest { + + private static final String IFACE_NAME = "iface"; + private static final int IFACE_INDEX = 3; + private static final String SRC_IFACE_NAME = "src-iface"; + private static final int SRC_IFACE_INDEX = 5; + + private NamingContext interfaceContext; + private MirroredInterfaceCustomizer customizer; + + private InstanceIdentifier validId; + private MirroredInterface validData; + + @Captor + private ArgumentCaptor requestCaptor; + + public void setUpTest() { + interfaceContext = new NamingContext("iface", "iface-context"); + customizer = + new MirroredInterfaceCustomizer(api, interfaceContext, id -> id.firstKeyOf(Interface.class).getName()); + defineMapping(mappingContext, IFACE_NAME, IFACE_INDEX, "iface-context"); + defineMapping(mappingContext, SRC_IFACE_NAME, SRC_IFACE_INDEX, "iface-context"); + + validId = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) + .augmentation(VppInterfaceAugmentation.class).child(Span.class) + .child(MirroredInterfaces.class) + .child(MirroredInterface.class); + + validData = new MirroredInterfaceBuilder() + .setIfaceRef(SRC_IFACE_NAME) + .setState(SpanState.Receive) + .build(); + + when(api.swInterfaceSpanEnableDisable(any())).thenReturn(future(new SwInterfaceSpanEnableDisableReply())); + } + + @Test + public void writeCurrentAttributes() throws Exception { + customizer.writeCurrentAttributes(validId, validData, writeContext); + verify(api, times(1)).swInterfaceSpanEnableDisable(requestCaptor.capture()); + assertCreateRequest(requestCaptor.getValue()); + } + + @Test + public void updateCurrentAttributes() throws Exception { + customizer.updateCurrentAttributes(validId, validData, validData, writeContext); + verify(api, times(2)).swInterfaceSpanEnableDisable(requestCaptor.capture()); + assertDeleteRequest(requestCaptor.getAllValues().get(0)); + assertCreateRequest(requestCaptor.getAllValues().get(1)); + } + + @Test + public void deleteCurrentAttributes() throws Exception { + customizer.deleteCurrentAttributes(validId, validData, writeContext); + verify(api, times(1)).swInterfaceSpanEnableDisable(requestCaptor.capture()); + assertDeleteRequest(requestCaptor.getValue()); + } + + private static void assertCreateRequest(final SwInterfaceSpanEnableDisable createRequest) { + assertNotNull(createRequest); + assertEquals(1, createRequest.state); + assertEquals(IFACE_INDEX, createRequest.swIfIndexTo); + assertEquals(SRC_IFACE_INDEX, createRequest.swIfIndexFrom); + } + + private static void assertDeleteRequest(final SwInterfaceSpanEnableDisable deleteRequest) { + assertNotNull(deleteRequest); + assertEquals(0, deleteRequest.state); + assertEquals(IFACE_INDEX, deleteRequest.swIfIndexTo); + assertEquals(SRC_IFACE_INDEX, deleteRequest.swIfIndexFrom); + } + +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/span/MirroredInterfacesCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/span/MirroredInterfacesCustomizerTest.java index 5d52e7634..3a4ce5dab 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/span/MirroredInterfacesCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/span/MirroredInterfacesCustomizerTest.java @@ -124,6 +124,6 @@ public class MirroredInterfacesCustomizerTest @Override protected ReaderCustomizer initCustomizer() { - return new MirroredInterfacesCustomizer(api, interfaceContext); + return new InterfaceMirroredInterfacesCustomizer(api, interfaceContext); } } \ No newline at end of file -- cgit 1.2.3-korg